home *** CD-ROM | disk | FTP | other *** search
/ Aminet 48 / Aminet 48 (2002)(GTI - Schatztruhe)[!][Apr 2002].iso / Aminet / text / edit / vim60src.lha / Vim / vim60 / src / term.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-09-21  |  133.6 KB  |  5,270 lines

  1. /* vi:set ts=8 sts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved    by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  * See README.txt for an overview of the Vim source code.
  8.  */
  9. /*
  10.  *
  11.  * term.c: functions for controlling the terminal
  12.  *
  13.  * primitive termcap support for Amiga, MSDOS, and Win32 included
  14.  *
  15.  * NOTE: padding and variable substitution is not performed,
  16.  * when compiling without HAVE_TGETENT, we use tputs() and tgoto() dummies.
  17.  */
  18.  
  19. /*
  20.  * Some systems have a prototype for tgetstr() with (char *) instead of
  21.  * (char **). This define removes that prototype. We include our own prototype
  22.  * below.
  23.  */
  24.  
  25. #define tgetstr tgetstr_defined_wrong
  26. #include "vim.h"
  27.  
  28. #ifdef HAVE_TGETENT
  29. # ifdef HAVE_TERMIOS_H
  30. #  include <termios.h>        /* seems to be required for some Linux */
  31. # endif
  32. # ifdef HAVE_TERMCAP_H
  33. #  include <termcap.h>
  34. # endif
  35.  
  36. /*
  37.  * A few linux systems define outfuntype in termcap.h to be used as the third
  38.  * argument for tputs().
  39.  */
  40. # ifdef VMS
  41. #  define TPUTSFUNCAST
  42. # else
  43. #  ifdef HAVE_OUTFUNTYPE
  44. #   define TPUTSFUNCAST (outfuntype)
  45. #  else
  46. #   define TPUTSFUNCAST (int (*)())
  47. #  endif
  48. # endif
  49. #endif
  50.  
  51. #undef tgetstr
  52.  
  53. /*
  54.  * Here are the builtin termcap entries.  They are not stored as complete
  55.  * Tcarr structures, as such a structure is too big.
  56.  *
  57.  * The entries are compact, therefore they normally are included even when
  58.  * HAVE_TGETENT is defined. When HAVE_TGETENT is defined, the builtin entries
  59.  * can be accessed with "builtin_amiga", "builtin_ansi", "builtin_debug", etc.
  60.  *
  61.  * Each termcap is a list of builtin_term structures. It always starts with
  62.  * KS_NAME, which separates the entries.  See parse_builtin_tcap() for all
  63.  * details.
  64.  * bt_entry is either a KS_xxx code (>= 0), or a K_xxx code.
  65.  *
  66.  * Entries marked with "guessed" may be wrong.
  67.  */
  68. struct builtin_term
  69. {
  70.     int        bt_entry;
  71.     char    *bt_string;
  72. };
  73.  
  74. /* start of keys that are not directly used by Vim but can be mapped */
  75. #define BT_EXTRA_KEYS    0x101
  76.  
  77. static struct builtin_term *find_builtin_term __ARGS((char_u *name));
  78. static void parse_builtin_tcap __ARGS((char_u *s));
  79. static void term_color __ARGS((char_u *s, int n));
  80. static void gather_termleader __ARGS((void));
  81. #ifdef FEAT_TERMRESPONSE
  82. static void req_codes_from_term __ARGS((void));
  83. static void req_more_codes_from_term __ARGS((void));
  84. static void got_code_from_term __ARGS((char_u *code, int len));
  85. static void check_for_codes_from_term __ARGS((void));
  86. #endif
  87. #if defined(FEAT_GUI) \
  88.     || (defined(FEAT_MOUSE) && (!defined(UNIX) || defined(FEAT_MOUSE_XTERM)))
  89. static int get_bytes_from_buf __ARGS((char_u *, char_u *, int));
  90. #endif
  91. #ifdef FEAT_TERMRESPONSE
  92. static void may_req_termresponse __ARGS((void));
  93. #endif
  94. static void del_termcode_idx __ARGS((int idx));
  95. static int term_is_builtin __ARGS((char_u *name));
  96. static int term_7to8bit __ARGS((char_u *p));
  97. #ifdef FEAT_TERMRESPONSE
  98. static void switch_to_8bit __ARGS((void));
  99. #endif
  100.  
  101. #ifdef HAVE_TGETENT
  102. static char_u *tgetent_error __ARGS((char_u *, char_u *));
  103.  
  104. /*
  105.  * Here is our own prototype for tgetstr(), any prototypes from the include
  106.  * files have been disabled by the define at the start of this file.
  107.  */
  108. char        *tgetstr __ARGS((char *, char **));
  109.  
  110. # ifdef FEAT_TERMRESPONSE
  111. /* Request Terminal Version status: */
  112. #  define CRV_GET    1    /* send T_CRV when switched to RAW mode */
  113. #  define CRV_SENT    2    /* did send T_CRV, waiting for answer */
  114. #  define CRV_GOT    3    /* received T_CRV response */
  115. static int crv_status = CRV_GET;
  116. # endif
  117.  
  118. /*
  119.  * Don't declare these variables if termcap.h contains them.
  120.  * Autoconf checks if these variables should be declared extern (not all
  121.  * systems have them).
  122.  * Some versions define ospeed to be speed_t, but that is incompatible with
  123.  * BSD, where ospeed is short and speed_t is long.
  124.  */
  125. # ifndef HAVE_OSPEED
  126. #  ifdef OSPEED_EXTERN
  127. extern short ospeed;
  128. #   else
  129. short ospeed;
  130. #   endif
  131. # endif
  132. # ifndef HAVE_UP_BC_PC
  133. #  ifdef UP_BC_PC_EXTERN
  134. extern char *UP, *BC, PC;
  135. #  else
  136. char *UP, *BC, PC;
  137. #  endif
  138. # endif
  139.  
  140. # define TGETSTR(s, p)    vim_tgetstr((s), (p))
  141. # define TGETENT(b, t)    tgetent((char *)(b), (char *)(t))
  142. static char_u *vim_tgetstr __ARGS((char *s, char_u **pp));
  143. #endif /* HAVE_TGETENT */
  144.  
  145. static int  detected_8bit = FALSE;    /* detected 8-bit terminal */
  146.  
  147. struct builtin_term builtin_termcaps[] =
  148. {
  149.  
  150. #if defined(FEAT_GUI)
  151. /*
  152.  * GUI pseudo term-cap.
  153.  */
  154.     {(int)KS_NAME,    "gui"},
  155.     {(int)KS_CE,    IF_EB("\033|$", ESC_STR "|$")},
  156.     {(int)KS_AL,    IF_EB("\033|i", ESC_STR "|i")},
  157. # ifdef TERMINFO
  158.     {(int)KS_CAL,    IF_EB("\033|%p1%dI", ESC_STR "|%p1%dI")},
  159. # else
  160.     {(int)KS_CAL,    IF_EB("\033|%dI", ESC_STR "|%dI")},
  161. # endif
  162.     {(int)KS_DL,    IF_EB("\033|d", ESC_STR "|d")},
  163. # ifdef TERMINFO
  164.     {(int)KS_CDL,    IF_EB("\033|%p1%dD", ESC_STR "|%p1%dD")},
  165.     {(int)KS_CS,    IF_EB("\033|%p1%d;%p2%dR", ESC_STR "|%p1%d;%p2%dR")},
  166. #  ifdef FEAT_VERTSPLIT
  167.     {(int)KS_CSV,    IF_EB("\033|%p1%d;%p2%dV", ESC_STR "|%p1%d;%p2%dV")},
  168. #  endif
  169. # else
  170.     {(int)KS_CDL,    IF_EB("\033|%dD", ESC_STR "|%dD")},
  171.     {(int)KS_CS,    IF_EB("\033|%d;%dR", ESC_STR "|%d;%dR")},
  172. #  ifdef FEAT_VERTSPLIT
  173.     {(int)KS_CSV,    IF_EB("\033|%d;%dV", ESC_STR "|%d;%dV")},
  174. #  endif
  175. # endif
  176.     {(int)KS_CL,    IF_EB("\033|C", ESC_STR "|C")},
  177.             /* attributes switched on with 'h', off with * 'H' */
  178.     {(int)KS_ME,    IF_EB("\033|31H", ESC_STR "|31H")}, /* HL_ALL */
  179.     {(int)KS_MR,    IF_EB("\033|1h", ESC_STR "|1h")},   /* HL_INVERSE */
  180.     {(int)KS_MD,    IF_EB("\033|2h", ESC_STR "|2h")},   /* HL_BOLD */
  181.     {(int)KS_SE,    IF_EB("\033|16H", ESC_STR "|16H")}, /* HL_STANDOUT */
  182.     {(int)KS_SO,    IF_EB("\033|16h", ESC_STR "|16h")}, /* HL_STANDOUT */
  183.     {(int)KS_UE,    IF_EB("\033|8H", ESC_STR "|8H")},   /* HL_UNDERLINE */
  184.     {(int)KS_US,    IF_EB("\033|8h", ESC_STR "|8h")},   /* HL_UNDERLINE */
  185.     {(int)KS_CZR,    IF_EB("\033|4H", ESC_STR "|4H")},   /* HL_ITALIC */
  186.     {(int)KS_CZH,    IF_EB("\033|4h", ESC_STR "|4h")},   /* HL_ITALIC */
  187.     {(int)KS_VB,    IF_EB("\033|f", ESC_STR "|f")},
  188.     {(int)KS_MS,    "y"},
  189.     {(int)KS_UT,    "y"},
  190.     {(int)KS_LE,    "\010"},    /* cursor-left = BS */
  191.     {(int)KS_ND,    "\014"},    /* cursor-right = CTRL-L */
  192. # ifdef TERMINFO
  193.     {(int)KS_CM,    IF_EB("\033|%p1%d;%p2%dM", ESC_STR "|%p1%d;%p2%dM")},
  194. # else
  195.     {(int)KS_CM,    IF_EB("\033|%d;%dM", ESC_STR "|%d;%dM")},
  196. # endif
  197.     /* there are no key sequences here, the GUI sequences are recognized
  198.      * in check_termcodes() */
  199. #endif
  200.  
  201. #ifndef NO_BUILTIN_TCAPS
  202. # if defined(RISCOS) || defined(ALL_BUILTIN_TCAPS)
  203. /*
  204.  * Default for the Acorn.
  205.  */
  206.     {(int)KS_NAME,    "riscos"},
  207.     {(int)KS_CL,    "\014"},        /* Cls and Home Cursor */
  208.     {(int)KS_CM,    "\001%d\001%d\002"},    /* Position cursor */
  209.  
  210.     {(int)KS_CCO,    "16"},            /* Allow 16 colors */
  211.  
  212.     {(int)KS_CAF,    "\001%d\021"},        /* Set foreground colour */
  213.     {(int)KS_CAB,    "\001%d\022"},        /* Set background colour */
  214.  
  215.  
  216.     {(int)KS_ME,    "\004"},        /* Normal mode */
  217.     {(int)KS_MR,    "\005"},        /* Reverse */
  218.  
  219.     {(int)KS_VI,    "\016"},        /* Cursor invisible */
  220.     {(int)KS_VE,    "\017"},        /* Cursor visible */
  221.     {(int)KS_VS,    "\020"},        /* Cursor very visible */
  222.  
  223.     {(int)KS_CS,    "\001%d\001%d\003"},    /* Set scroll region */
  224.     {(int)KS_SR,    "\023"},        /* Scroll text down */
  225.     {K_UP,        "\217"},
  226.     {K_DOWN,        "\216"},
  227.     {K_LEFT,        "\214"},
  228.     {K_RIGHT,        "\215"},
  229.     {K_S_UP,        "\237"},
  230.     {K_S_DOWN,        "\236"},
  231.     {K_S_LEFT,        "\234"},
  232.     {K_S_RIGHT,        "\235"},
  233.  
  234.     {K_F1,        "\201"},
  235.     {K_F2,        "\202"},
  236.     {K_F3,        "\203"},
  237.     {K_F4,        "\204"},
  238.     {K_F5,        "\205"},
  239.     {K_F6,        "\206"},
  240.     {K_F7,        "\207"},
  241.     {K_F8,        "\210"},
  242.     {K_F9,        "\211"},
  243.     {K_F10,        "\312"},
  244.     {K_F11,        "\313"},
  245.     {K_F12,        "\314"},
  246.     {K_S_F1,        "\221"},
  247.     {K_S_F2,        "\222"},
  248.     {K_S_F3,        "\223"},
  249.     {K_S_F4,        "\224"},
  250.     {K_S_F5,        "\225"},
  251.     {K_S_F6,        "\226"},
  252.     {K_S_F7,        "\227"},
  253.     {K_S_F8,        "\230"},
  254.     {K_S_F9,        "\231"},
  255.     {K_S_F10,        "\332"},
  256.     {K_S_F11,        "\333"},
  257.     {K_S_F12,        "\334"},
  258.     {K_BS,        "\010"},
  259.     {K_INS,        "\315"},
  260.     {K_DEL,        "\177"},
  261.     {K_HOME,        "\036"},
  262.     {K_END,        "\213"},
  263.     {K_PAGEUP,        "\237"},
  264.     {K_PAGEDOWN,    "\236"},
  265. # endif    /* Acorn terminal */
  266.  
  267.  
  268. # if defined(AMIGA) || defined(ALL_BUILTIN_TCAPS)
  269. /*
  270.  * Amiga console window, default for Amiga
  271.  */
  272.     {(int)KS_NAME,    "amiga"},
  273.     {(int)KS_CE,    "\033[K"},
  274.     {(int)KS_CD,    "\033[J"},
  275.     {(int)KS_AL,    "\033[L"},
  276. #  ifdef TERMINFO
  277.     {(int)KS_CAL,    "\033[%p1%dL"},
  278. #  else
  279.     {(int)KS_CAL,    "\033[%dL"},
  280. #  endif
  281.     {(int)KS_DL,    "\033[M"},
  282. #  ifdef TERMINFO
  283.     {(int)KS_CDL,    "\033[%p1%dM"},
  284. #  else
  285.     {(int)KS_CDL,    "\033[%dM"},
  286. #  endif
  287.     {(int)KS_CL,    "\014"},
  288.     {(int)KS_VI,    "\033[0 p"},
  289.     {(int)KS_VE,    "\033[1 p"},
  290.     {(int)KS_ME,    "\033[0m"},
  291.     {(int)KS_MR,    "\033[7m"},
  292.     {(int)KS_MD,    "\033[1m"},
  293.     {(int)KS_SE,    "\033[0m"},
  294.     {(int)KS_SO,    "\033[33m"},
  295.     {(int)KS_US,    "\033[4m"},
  296.     {(int)KS_UE,    "\033[0m"},
  297.     {(int)KS_CZH,    "\033[3m"},
  298.     {(int)KS_CZR,    "\033[0m"},
  299.     {(int)KS_MS,    "y"},
  300.     {(int)KS_UT,    "y"},        /* guessed */
  301.     {(int)KS_LE,    "\010"},
  302. #  ifdef TERMINFO
  303.     {(int)KS_CM,    "\033[%i%p1%d;%p2%dH"},
  304. #  else
  305.     {(int)KS_CM,    "\033[%i%d;%dH"},
  306. #  endif
  307. #  ifdef TERMINFO
  308.     {(int)KS_CRI,    "\033[%p1%dC"},
  309. #  else
  310.     {(int)KS_CRI,    "\033[%dC"},
  311. #  endif
  312.     {K_UP,        "\233A"},
  313.     {K_DOWN,        "\233B"},
  314.     {K_LEFT,        "\233D"},
  315.     {K_RIGHT,        "\233C"},
  316.     {K_S_UP,        "\233T"},
  317.     {K_S_DOWN,        "\233S"},
  318.     {K_S_LEFT,        "\233 A"},
  319.     {K_S_RIGHT,        "\233 @"},
  320.     {K_S_TAB,        "\233Z"},
  321.     {K_F1,        "\233\060~"},/* some compilers don't dig "\2330" */
  322.     {K_F2,        "\233\061~"},
  323.     {K_F3,        "\233\062~"},
  324.     {K_F4,        "\233\063~"},
  325.     {K_F5,        "\233\064~"},
  326.     {K_F6,        "\233\065~"},
  327.     {K_F7,        "\233\066~"},
  328.     {K_F8,        "\233\067~"},
  329.     {K_F9,        "\233\070~"},
  330.     {K_F10,        "\233\071~"},
  331.     {K_S_F1,        "\233\061\060~"},
  332.     {K_S_F2,        "\233\061\061~"},
  333.     {K_S_F3,        "\233\061\062~"},
  334.     {K_S_F4,        "\233\061\063~"},
  335.     {K_S_F5,        "\233\061\064~"},
  336.     {K_S_F6,        "\233\061\065~"},
  337.     {K_S_F7,        "\233\061\066~"},
  338.     {K_S_F8,        "\233\061\067~"},
  339.     {K_S_F9,        "\233\061\070~"},
  340.     {K_S_F10,        "\233\061\071~"},
  341.     {K_HELP,        "\233?~"},
  342.     {K_INS,        "\233\064\060~"},    /* 101 key keyboard */
  343.     {K_PAGEUP,        "\233\064\061~"},    /* 101 key keyboard */
  344.     {K_PAGEDOWN,    "\233\064\062~"},    /* 101 key keyboard */
  345.     {K_HOME,        "\233\064\064~"},    /* 101 key keyboard */
  346.     {K_END,        "\233\064\065~"},    /* 101 key keyboard */
  347.  
  348.     {BT_EXTRA_KEYS,    ""},
  349.     {TERMCAP2KEY('#', '2'), "\233\065\064~"},    /* shifted home key */
  350.     {TERMCAP2KEY('#', '3'), "\233\065\060~"},    /* shifted insert key */
  351.     {TERMCAP2KEY('*', '7'), "\233\065\065~"},    /* shifted end key */
  352. # endif
  353.  
  354. # if defined(__BEOS__) || defined(ALL_BUILTIN_TCAPS)
  355. /*
  356.  * almost standard ANSI terminal, default for bebox
  357.  */
  358.     {(int)KS_NAME,    "beos-ansi"},
  359.     {(int)KS_CE,    "\033[K"},
  360.     {(int)KS_CD,    "\033[J"},
  361.     {(int)KS_AL,    "\033[L"},
  362. #  ifdef TERMINFO
  363.     {(int)KS_CAL,    "\033[%p1%dL"},
  364. #  else
  365.     {(int)KS_CAL,    "\033[%dL"},
  366. #  endif
  367.     {(int)KS_DL,    "\033[M"},
  368. #  ifdef TERMINFO
  369.     {(int)KS_CDL,    "\033[%p1%dM"},
  370. #  else
  371.     {(int)KS_CDL,    "\033[%dM"},
  372. #  endif
  373. #ifdef BEOS_PR_OR_BETTER
  374. #  ifdef TERMINFO
  375.     {(int)KS_CS,    "\033[%i%p1%d;%p2%dr"},
  376. #  else
  377.     {(int)KS_CS,    "\033[%i%d;%dr"},    /* scroll region */
  378. #  endif
  379. #endif
  380.     {(int)KS_CL,    "\033[H\033[2J"},
  381. #ifdef notyet
  382.     {(int)KS_VI,    "[VI]"}, /* cursor invisible, VT320: CSI ? 25 l */
  383.     {(int)KS_VE,    "[VE]"}, /* cursor visible, VT320: CSI ? 25 h */
  384. #endif
  385.     {(int)KS_ME,    "\033[m"},    /* normal mode */
  386.     {(int)KS_MR,    "\033[7m"},    /* reverse */
  387.     {(int)KS_MD,    "\033[1m"},    /* bold */
  388.     {(int)KS_SO,    "\033[31m"},    /* standout mode: red */
  389.     {(int)KS_SE,    "\033[m"},    /* standout end */
  390.     {(int)KS_CZH,    "\033[35m"},    /* italic: purple */
  391.     {(int)KS_CZR,    "\033[m"},    /* italic end */
  392.     {(int)KS_US,    "\033[4m"},    /* underscore mode */
  393.     {(int)KS_UE,    "\033[m"},    /* underscore end */
  394.     {(int)KS_CCO,    "8"},        /* allow 8 colors */
  395. #  ifdef TERMINFO
  396.     {(int)KS_CAB,    "\033[4%p1%dm"},/* set background color */
  397.     {(int)KS_CAF,    "\033[3%p1%dm"},/* set foreground color */
  398. #  else
  399.     {(int)KS_CAB,    "\033[4%dm"},    /* set background color */
  400.     {(int)KS_CAF,    "\033[3%dm"},    /* set foreground color */
  401. #  endif
  402.     {(int)KS_OP,    "\033[m"},    /* reset colors */
  403.     {(int)KS_MS,    "y"},        /* safe to move cur in reverse mode */
  404.     {(int)KS_UT,    "y"},        /* guessed */
  405.     {(int)KS_LE,    "\010"},
  406. #  ifdef TERMINFO
  407.     {(int)KS_CM,    "\033[%i%p1%d;%p2%dH"},
  408. #  else
  409.     {(int)KS_CM,    "\033[%i%d;%dH"},
  410. #  endif
  411.     {(int)KS_SR,    "\033M"},
  412. #  ifdef TERMINFO
  413.     {(int)KS_CRI,    "\033[%p1%dC"},
  414. #  else
  415.     {(int)KS_CRI,    "\033[%dC"},
  416. #  endif
  417. #if defined(BEOS_DR8)
  418.     {(int)KS_DB,    ""},        /* hack! see screen.c */
  419. #endif
  420.  
  421.     {K_UP,        "\033[A"},
  422.     {K_DOWN,        "\033[B"},
  423.     {K_LEFT,        "\033[D"},
  424.     {K_RIGHT,        "\033[C"},
  425. # endif
  426.  
  427. # if defined(UNIX) || defined(ALL_BUILTIN_TCAPS) || defined(SOME_BUILTIN_TCAPS) || defined(__EMX__)
  428. /*
  429.  * standard ANSI terminal, default for unix
  430.  */
  431.     {(int)KS_NAME,    "ansi"},
  432.     {(int)KS_CE,    IF_EB("\033[K", ESC_STR "[K")},
  433.     {(int)KS_AL,    IF_EB("\033[L", ESC_STR "[L")},
  434. #  ifdef TERMINFO
  435.     {(int)KS_CAL,    IF_EB("\033[%p1%dL", ESC_STR "[%p1%dL")},
  436. #  else
  437.     {(int)KS_CAL,    IF_EB("\033[%dL", ESC_STR "[%dL")},
  438. #  endif
  439.     {(int)KS_DL,    IF_EB("\033[M", ESC_STR "[M")},
  440. #  ifdef TERMINFO
  441.     {(int)KS_CDL,    IF_EB("\033[%p1%dM", ESC_STR "[%p1%dM")},
  442. #  else
  443.     {(int)KS_CDL,    IF_EB("\033[%dM", ESC_STR "[%dM")},
  444. #  endif
  445.     {(int)KS_CL,    IF_EB("\033[H\033[2J", ESC_STR "[H" ESC_STR_nc "[2J")},
  446.     {(int)KS_ME,    IF_EB("\033[0m", ESC_STR "[0m")},
  447.     {(int)KS_MR,    IF_EB("\033[7m", ESC_STR "[7m")},
  448.     {(int)KS_MS,    "y"},
  449.     {(int)KS_UT,    "y"},        /* guessed */
  450.     {(int)KS_LE,    "\010"},
  451. #  ifdef TERMINFO
  452.     {(int)KS_CM,    IF_EB("\033[%i%p1%d;%p2%dH", ESC_STR "[%i%p1%d;%p2%dH")},
  453. #  else
  454.     {(int)KS_CM,    IF_EB("\033[%i%d;%dH", ESC_STR "[%i%d;%dH")},
  455. #  endif
  456. #  ifdef TERMINFO
  457.     {(int)KS_CRI,    IF_EB("\033[%p1%dC", ESC_STR "[%p1%dC")},
  458. #  else
  459.     {(int)KS_CRI,    IF_EB("\033[%dC", ESC_STR "[%dC")},
  460. #  endif
  461. # endif
  462.  
  463. # if defined(MSDOS) || defined(ALL_BUILTIN_TCAPS) || defined(__EMX__)
  464. /*
  465.  * These codes are valid when nansi.sys or equivalent has been installed.
  466.  * Function keys on a PC are preceded with a NUL. These are converted into
  467.  * K_NUL '\316' in mch_inchar(), because we cannot handle NULs in key codes.
  468.  * CTRL-arrow is used instead of SHIFT-arrow.
  469.  */
  470. #ifdef __EMX__
  471.     {(int)KS_NAME,    "os2ansi"},
  472. #else
  473.     {(int)KS_NAME,    "pcansi"},
  474.     {(int)KS_DL,    "\033[M"},
  475.     {(int)KS_AL,    "\033[L"},
  476. #endif
  477.     {(int)KS_CE,    "\033[K"},
  478.     {(int)KS_CL,    "\033[2J"},
  479.     {(int)KS_ME,    "\033[0m"},
  480.     {(int)KS_MR,    "\033[5m"},    /* reverse: black on lightgrey */
  481.     {(int)KS_MD,    "\033[1m"},    /* bold: white text */
  482.     {(int)KS_SE,    "\033[0m"},    /* standout end */
  483.     {(int)KS_SO,    "\033[31m"},    /* standout: white on blue */
  484.     {(int)KS_CZH,    "\033[34;43m"},    /* italic mode: blue text on yellow */
  485.     {(int)KS_CZR,    "\033[0m"},    /* italic mode end */
  486.     {(int)KS_US,    "\033[36;41m"},    /* underscore mode: cyan text on red */
  487.     {(int)KS_UE,    "\033[0m"},    /* underscore mode end */
  488.     {(int)KS_CCO,    "8"},        /* allow 8 colors */
  489. #  ifdef TERMINFO
  490.     {(int)KS_CAB,    "\033[4%p1%dm"},/* set background color */
  491.     {(int)KS_CAF,    "\033[3%p1%dm"},/* set foreground color */
  492. #  else
  493.     {(int)KS_CAB,    "\033[4%dm"},    /* set background color */
  494.     {(int)KS_CAF,    "\033[3%dm"},    /* set foreground color */
  495. #  endif
  496.     {(int)KS_OP,    "\033[0m"},    /* reset colors */
  497.     {(int)KS_MS,    "y"},
  498.     {(int)KS_UT,    "y"},        /* guessed */
  499.     {(int)KS_LE,    "\010"},
  500. #  ifdef TERMINFO
  501.     {(int)KS_CM,    "\033[%i%p1%d;%p2%dH"},
  502. #  else
  503.     {(int)KS_CM,    "\033[%i%d;%dH"},
  504. #  endif
  505. #  ifdef TERMINFO
  506.     {(int)KS_CRI,    "\033[%p1%dC"},
  507. #  else
  508.     {(int)KS_CRI,    "\033[%dC"},
  509. #  endif
  510.     {K_UP,        "\316H"},
  511.     {K_DOWN,        "\316P"},
  512.     {K_LEFT,        "\316K"},
  513.     {K_RIGHT,        "\316M"},
  514.     {K_S_LEFT,        "\316s"},
  515.     {K_S_RIGHT,        "\316t"},
  516.     {K_F1,        "\316;"},
  517.     {K_F2,        "\316<"},
  518.     {K_F3,        "\316="},
  519.     {K_F4,        "\316>"},
  520.     {K_F5,        "\316?"},
  521.     {K_F6,        "\316@"},
  522.     {K_F7,        "\316A"},
  523.     {K_F8,        "\316B"},
  524.     {K_F9,        "\316C"},
  525.     {K_F10,        "\316D"},
  526.     {K_F11,        "\316\205"},    /* guessed */
  527.     {K_F12,        "\316\206"},    /* guessed */
  528.     {K_S_F1,        "\316T"},
  529.     {K_S_F2,        "\316U"},
  530.     {K_S_F3,        "\316V"},
  531.     {K_S_F4,        "\316W"},
  532.     {K_S_F5,        "\316X"},
  533.     {K_S_F6,        "\316Y"},
  534.     {K_S_F7,        "\316Z"},
  535.     {K_S_F8,        "\316["},
  536.     {K_S_F9,        "\316\\"},
  537.     {K_S_F10,        "\316]"},
  538.     {K_S_F11,        "\316\207"},    /* guessed */
  539.     {K_S_F12,        "\316\210"},    /* guessed */
  540.     {K_INS,        "\316R"},
  541.     {K_DEL,        "\316S"},
  542.     {K_HOME,        "\316G"},
  543.     {K_END,        "\316O"},
  544.     {K_PAGEDOWN,    "\316Q"},
  545.     {K_PAGEUP,        "\316I"},
  546. # endif
  547.  
  548. # if defined(MSDOS)
  549. /*
  550.  * These codes are valid for the pc video.  The entries that start with ESC |
  551.  * are translated into conio calls in os_msdos.c. Default for MSDOS.
  552.  */
  553.     {(int)KS_NAME,    "pcterm"},
  554.     {(int)KS_CE,    "\033|K"},
  555.     {(int)KS_AL,    "\033|L"},
  556.     {(int)KS_DL,    "\033|M"},
  557. #  ifdef TERMINFO
  558.     {(int)KS_CS,    "\033|%i%p1%d;%p2%dr"},
  559. #   ifdef FEAT_VERTSPLIT
  560.     {(int)KS_CSV,    "\033|%i%p1%d;%p2%dV"},
  561. #   endif
  562. #  else
  563.     {(int)KS_CS,    "\033|%i%d;%dr"},
  564. #   ifdef FEAT_VERTSPLIT
  565.     {(int)KS_CSV,    "\033|%i%d;%dV"},
  566. #   endif
  567. #  endif
  568.     {(int)KS_CL,    "\033|J"},
  569.     {(int)KS_ME,    "\033|0m"},    /* normal */
  570.     {(int)KS_MR,    "\033|112m"},    /* reverse: black on lightgrey */
  571.     {(int)KS_MD,    "\033|15m"},    /* bold: white text */
  572.     {(int)KS_SE,    "\033|0m"},    /* standout end */
  573.     {(int)KS_SO,    "\033|31m"},    /* standout: white on blue */
  574.     {(int)KS_CZH,    "\033|225m"},    /* italic mode: blue text on yellow */
  575.     {(int)KS_CZR,    "\033|0m"},    /* italic mode end */
  576.     {(int)KS_US,    "\033|67m"},    /* underscore mode: cyan text on red */
  577.     {(int)KS_UE,    "\033|0m"},    /* underscore mode end */
  578.     {(int)KS_CCO,    "16"},        /* allow 16 colors */
  579. #  ifdef TERMINFO
  580.     {(int)KS_CAB,    "\033|%p1%db"},    /* set background color */
  581.     {(int)KS_CAF,    "\033|%p1%df"},    /* set foreground color */
  582. #  else
  583.     {(int)KS_CAB,    "\033|%db"},    /* set background color */
  584.     {(int)KS_CAF,    "\033|%df"},    /* set foreground color */
  585. #  endif
  586.     {(int)KS_MS,    "y"},
  587.     {(int)KS_UT,    "y"},
  588.     {(int)KS_LE,    "\010"},
  589. #  ifdef TERMINFO
  590.     {(int)KS_CM,    "\033|%i%p1%d;%p2%dH"},
  591. #  else
  592.     {(int)KS_CM,    "\033|%i%d;%dH"},
  593. #  endif
  594. #ifdef DJGPP
  595.     {(int)KS_VB,    "\033|B"},    /* visual bell */
  596. #endif
  597.     {K_UP,        "\316H"},
  598.     {K_DOWN,        "\316P"},
  599.     {K_LEFT,        "\316K"},
  600.     {K_RIGHT,        "\316M"},
  601.     {K_S_LEFT,        "\316s"},
  602.     {K_S_RIGHT,        "\316t"},
  603.     {K_S_TAB,        "\316\017"},
  604.     {K_F1,        "\316;"},
  605.     {K_F2,        "\316<"},
  606.     {K_F3,        "\316="},
  607.     {K_F4,        "\316>"},
  608.     {K_F5,        "\316?"},
  609.     {K_F6,        "\316@"},
  610.     {K_F7,        "\316A"},
  611.     {K_F8,        "\316B"},
  612.     {K_F9,        "\316C"},
  613.     {K_F10,        "\316D"},
  614.     {K_F11,        "\316\205"},
  615.     {K_F12,        "\316\206"},
  616.     {K_S_F1,        "\316T"},
  617.     {K_S_F2,        "\316U"},
  618.     {K_S_F3,        "\316V"},
  619.     {K_S_F4,        "\316W"},
  620.     {K_S_F5,        "\316X"},
  621.     {K_S_F6,        "\316Y"},
  622.     {K_S_F7,        "\316Z"},
  623.     {K_S_F8,        "\316["},
  624.     {K_S_F9,        "\316\\"},
  625.     {K_S_F10,        "\316]"},
  626.     {K_S_F11,        "\316\207"},
  627.     {K_S_F12,        "\316\210"},
  628.     {K_INS,        "\316R"},
  629.     {K_DEL,        "\316S"},
  630.     {K_HOME,        "\316G"},
  631.     {K_END,        "\316O"},
  632.     {K_PAGEDOWN,    "\316Q"},
  633.     {K_PAGEUP,        "\316I"},
  634.     {K_KPLUS,        "\316N"},
  635.     {K_KMINUS,        "\316J"},
  636.     {K_KMULTIPLY,    "\3167"},
  637.     {K_K0,        "\316\332"},
  638.     {K_K1,        "\316\336"},
  639.     {K_K2,        "\316\342"},
  640.     {K_K3,        "\316\346"},
  641.     {K_K4,        "\316\352"},
  642.     {K_K5,        "\316\356"},
  643.     {K_K6,        "\316\362"},
  644.     {K_K7,        "\316\366"},
  645.     {K_K8,        "\316\372"},
  646.     {K_K9,        "\316\376"},
  647. # endif
  648.  
  649. # if defined(WIN3264) || defined(ALL_BUILTIN_TCAPS) || defined(__EMX__)
  650. /*
  651.  * These codes are valid for the Win32 Console .  The entries that start with
  652.  * ESC | are translated into console calls in os_win32.c.  The function keys
  653.  * are also translated in os_win32.c.
  654.  */
  655.     {(int)KS_NAME,    "win32"},
  656.     {(int)KS_CE,    "\033|K"},    /* clear to end of line */
  657.     {(int)KS_AL,    "\033|L"},    /* add new blank line */
  658. #  ifdef TERMINFO
  659.     {(int)KS_CAL,    "\033|%p1%dL"},    /* add number of new blank lines */
  660. #  else
  661.     {(int)KS_CAL,    "\033|%dL"},    /* add number of new blank lines */
  662. #  endif
  663.     {(int)KS_DL,    "\033|M"},    /* delete line */
  664. #  ifdef TERMINFO
  665.     {(int)KS_CDL,    "\033|%p1%dM"},    /* delete number of lines */
  666. #  else
  667.     {(int)KS_CDL,    "\033|%dM"},    /* delete number of lines */
  668. #  endif
  669.     {(int)KS_CL,    "\033|J"},    /* clear screen */
  670.     {(int)KS_CD,    "\033|j"},    /* clear to end of display */
  671.     {(int)KS_VI,    "\033|v"},    /* cursor invisible */
  672.     {(int)KS_VE,    "\033|V"},    /* cursor visible */
  673.  
  674.     {(int)KS_ME,    "\033|0m"},    /* normal */
  675.     {(int)KS_MR,    "\033|112m"},    /* reverse: black on lightgray */
  676.     {(int)KS_MD,    "\033|15m"},    /* bold: white on black */
  677. #if 1
  678.     {(int)KS_SO,    "\033|31m"},    /* standout: white on blue */
  679.     {(int)KS_SE,    "\033|0m"},    /* standout end */
  680. #else
  681.     {(int)KS_SO,    "\033|F"},    /* standout: high intensity */
  682.     {(int)KS_SE,    "\033|f"},    /* standout end */
  683. #endif
  684.     {(int)KS_CZH,    "\033|225m"},    /* italic: blue text on yellow */
  685.     {(int)KS_CZR,    "\033|0m"},    /* italic end */
  686.     {(int)KS_US,    "\033|67m"},    /* underscore: cyan text on red */
  687.     {(int)KS_UE,    "\033|0m"},    /* underscore end */
  688.     {(int)KS_CCO,    "16"},        /* allow 16 colors */
  689. #  ifdef TERMINFO
  690.     {(int)KS_CAB,    "\033|%p1%db"},    /* set background color */
  691.     {(int)KS_CAF,    "\033|%p1%df"},    /* set foreground color */
  692. #  else
  693.     {(int)KS_CAB,    "\033|%db"},    /* set background color */
  694.     {(int)KS_CAF,    "\033|%df"},    /* set foreground color */
  695. #  endif
  696.  
  697.     {(int)KS_MS,    "y"},        /* save to move cur in reverse mode */
  698.     {(int)KS_UT,    "y"},
  699.     {(int)KS_LE,    "\010"},
  700. #  ifdef TERMINFO
  701.     {(int)KS_CM,    "\033|%i%p1%d;%p2%dH"},/* cursor motion */
  702. #  else
  703.     {(int)KS_CM,    "\033|%i%d;%dH"},/* cursor motion */
  704. #  endif
  705.     {(int)KS_VB,    "\033|B"},    /* visual bell */
  706.     {(int)KS_TI,    "\033|S"},    /* put terminal in termcap mode */
  707.     {(int)KS_TE,    "\033|E"},    /* out of termcap mode */
  708. #  ifdef TERMINFO
  709.     {(int)KS_CS,    "\033|%i%p1%d;%p2%dr"},/* scroll region */
  710. #  else
  711.     {(int)KS_CS,    "\033|%i%d;%dr"},/* scroll region */
  712. #  endif
  713.  
  714.     {K_UP,        "\316H"},
  715.     {K_DOWN,        "\316P"},
  716.     {K_LEFT,        "\316K"},
  717.     {K_RIGHT,        "\316M"},
  718.     {K_S_UP,        "\316\304"},
  719.     {K_S_DOWN,        "\316\317"},
  720.     {K_S_LEFT,        "\316\311"},
  721.     {K_C_LEFT,        "\316s"},
  722.     {K_S_RIGHT,        "\316\313"},
  723.     {K_C_RIGHT,        "\316t"},
  724.     {K_S_TAB,        "\316\017"},
  725.     {K_F1,        "\316;"},
  726.     {K_F2,        "\316<"},
  727.     {K_F3,        "\316="},
  728.     {K_F4,        "\316>"},
  729.     {K_F5,        "\316?"},
  730.     {K_F6,        "\316@"},
  731.     {K_F7,        "\316A"},
  732.     {K_F8,        "\316B"},
  733.     {K_F9,        "\316C"},
  734.     {K_F10,        "\316D"},
  735.     {K_F11,        "\316\205"},
  736.     {K_F12,        "\316\206"},
  737.     {K_S_F1,        "\316T"},
  738.     {K_S_F2,        "\316U"},
  739.     {K_S_F3,        "\316V"},
  740.     {K_S_F4,        "\316W"},
  741.     {K_S_F5,        "\316X"},
  742.     {K_S_F6,        "\316Y"},
  743.     {K_S_F7,        "\316Z"},
  744.     {K_S_F8,        "\316["},
  745.     {K_S_F9,        "\316\\"},
  746.     {K_S_F10,        "\316]"},
  747.     {K_S_F11,        "\316\207"},
  748.     {K_S_F12,        "\316\210"},
  749.     {K_INS,        "\316R"},
  750.     {K_DEL,        "\316S"},
  751.     {K_HOME,        "\316G"},
  752.     {K_S_HOME,        "\316\302"},
  753.     {K_C_HOME,        "\316w"},
  754.     {K_END,        "\316O"},
  755.     {K_S_END,        "\316\315"},
  756.     {K_C_END,        "\316u"},
  757.     {K_PAGEDOWN,    "\316Q"},
  758.     {K_PAGEUP,        "\316I"},
  759.     {K_KPLUS,        "\316N"},
  760.     {K_KMINUS,        "\316J"},
  761.     {K_KMULTIPLY,    "\316\067"},
  762.     {K_K0,        "\316\332"},
  763.     {K_K1,        "\316\336"},
  764.     {K_K2,        "\316\342"},
  765.     {K_K3,        "\316\346"},
  766.     {K_K4,        "\316\352"},
  767.     {K_K5,        "\316\356"},
  768.     {K_K6,        "\316\362"},
  769.     {K_K7,        "\316\366"},
  770.     {K_K8,        "\316\372"},
  771.     {K_K9,        "\316\376"},
  772. # endif
  773.  
  774. # if defined(VMS) || defined(ALL_BUILTIN_TCAPS)
  775. /*
  776.  * VT320 is working as an ANSI terminal compatible DEC terminal.
  777.  * (it covers VT1x0, VT2x0 and VT3x0 up to VT320 on VMS as well)
  778.  * Note: K_F1...K_F5 are for internal use, should not be defined.
  779.  * TODO:- rewrite ESC[ codes to CSI
  780.  *      - keyboard languages (CSI ? 26 n)
  781.  */
  782.     {(int)KS_NAME,    "vt320"},
  783.     {(int)KS_CE,    IF_EB("\033[K", ESC_STR "[K")},
  784.     {(int)KS_AL,    IF_EB("\033[L", ESC_STR "[L")},
  785. #  ifdef TERMINFO
  786.     {(int)KS_CAL,    IF_EB("\033[%p1%dL", ESC_STR "[%p1%dL")},
  787. #  else
  788.     {(int)KS_CAL,    IF_EB("\033[%dL", ESC_STR "[%dL")},
  789. #  endif
  790.     {(int)KS_DL,    IF_EB("\033[M", ESC_STR "[M")},
  791. #  ifdef TERMINFO
  792.     {(int)KS_CDL,    IF_EB("\033[%p1%dM", ESC_STR "[%p1%dM")},
  793. #  else
  794.     {(int)KS_CDL,    IF_EB("\033[%dM", ESC_STR "[%dM")},
  795. #  endif
  796.     {(int)KS_CL,    IF_EB("\033[H\033[2J", ESC_STR "[H" ESC_STR_nc "[2J")},
  797.     {(int)KS_ME,    IF_EB("\033[0m", ESC_STR "[0m")},
  798.     {(int)KS_MR,    IF_EB("\033[7m", ESC_STR "[7m")},
  799.     {(int)KS_MS,    "y"},
  800.     {(int)KS_UT,    "y"},
  801.     {(int)KS_LE,    "\010"},
  802. #  ifdef TERMINFO
  803.     {(int)KS_CM,    IF_EB("\033[%i%p1%d;%p2%dH",
  804.                           ESC_STR "[%i%p1%d;%p2%dH")},
  805. #  else
  806.     {(int)KS_CM,    IF_EB("\033[%i%d;%dH", ESC_STR "[%i%d;%dH")},
  807. #  endif
  808. #  ifdef TERMINFO
  809.     {(int)KS_CRI,    IF_EB("\033[%p1%dC", ESC_STR "[%p1%dC")},
  810. #  else
  811.     {(int)KS_CRI,    IF_EB("\033[%dC", ESC_STR "[%dC")},
  812. #  endif
  813.     {K_UP,        IF_EB("\033[A", ESC_STR "[A")},
  814.     {K_DOWN,        IF_EB("\033[B", ESC_STR "[B")},
  815.     {K_RIGHT,        IF_EB("\033[C", ESC_STR "[C")},
  816.     {K_LEFT,        IF_EB("\033[D", ESC_STR "[D")},
  817.     {K_F6,        IF_EB("\033[17~", ESC_STR "[17~")},
  818.     {K_F7,        IF_EB("\033[18~", ESC_STR "[18~")},
  819.     {K_F8,        IF_EB("\033[19~", ESC_STR "[19~")},
  820.     {K_F9,        IF_EB("\033[20~", ESC_STR "[20~")},
  821.     {K_F10,        IF_EB("\033[21~", ESC_STR "[21~")},
  822. /*  {K_F11,        IF_EB("\033[23~", ESC_STR "[23~")},
  823.             *  (ESC) should not define, sometimes does not work */
  824.     {K_F12,        IF_EB("\033[24~", ESC_STR "[24~")},
  825.     {K_F13,        IF_EB("\033[25~", ESC_STR "[25~")},
  826.     {K_F14,        IF_EB("\033[26~", ESC_STR "[26~")},
  827.     {K_F15,        IF_EB("\033[28~", ESC_STR "[28~")},    /* Help */
  828.     {K_F16,        IF_EB("\033[29~", ESC_STR "[29~")},    /* Select */
  829.     {K_F17,        IF_EB("\033[31~", ESC_STR "[31~")},
  830.     {K_F18,        IF_EB("\033[32~", ESC_STR "[32~")},
  831.     {K_F19,        IF_EB("\033[33~", ESC_STR "[33~")},
  832.     {K_F20,        IF_EB("\033[34~", ESC_STR "[34~")},
  833.     {K_INS,        IF_EB("\033[2~", ESC_STR "[2~")},
  834.     {K_DEL,        IF_EB("\033[3~", ESC_STR "[3~")},
  835.     {K_HOME,        IF_EB("\033[1~", ESC_STR "[1~")},
  836.     {K_END,        IF_EB("\033[4~", ESC_STR "[4~")},
  837.     {K_PAGEUP,        IF_EB("\033[5~", ESC_STR "[5~")},
  838.     {K_PAGEDOWN,    IF_EB("\033[6~", ESC_STR "[6~")},
  839.     {K_KPLUS,        IF_EB("\033Ok", ESC_STR "Ok")},    /* keypad plus */
  840.     {K_KMINUS,        IF_EB("\033Om", ESC_STR "Om")},    /* keypad minus */
  841.     {K_KDIVIDE,        IF_EB("\033Oo", ESC_STR "Oo")},    /* keypad / */
  842.     {K_KMULTIPLY,    IF_EB("\033Oj", ESC_STR "Oj")},    /* keypad * */
  843.     {K_KENTER,        IF_EB("\033OM", ESC_STR "OM")},    /* keypad Enter */
  844.     {K_BS,        "\x7f"},    /* for some reason 0177 doesn't work */
  845. # endif
  846.  
  847. # if defined(ALL_BUILTIN_TCAPS) || defined(__MINT__)
  848. /*
  849.  * Ordinary vt52
  850.  */
  851.     {(int)KS_NAME,    "vt52"},
  852.     {(int)KS_CE,    IF_EB("\033K", ESC_STR "K")},
  853.     {(int)KS_CD,    IF_EB("\033J", ESC_STR "J")},
  854.     {(int)KS_CM,    IF_EB("\033Y%+ %+ ", ESC_STR "Y%+ %+ ")},
  855.     {(int)KS_LE,    "\010"},
  856. #  ifdef __MINT__
  857.     {(int)KS_AL,    IF_EB("\033L", ESC_STR "L")},
  858.     {(int)KS_DL,    IF_EB("\033M", ESC_STR "M")},
  859.     {(int)KS_CL,    IF_EB("\033E", ESC_STR "E")},
  860.     {(int)KS_SR,    IF_EB("\033I", ESC_STR "I")},
  861.     {(int)KS_VE,    IF_EB("\033e", ESC_STR "e")},
  862.     {(int)KS_VI,    IF_EB("\033f", ESC_STR "f")},
  863.     {(int)KS_SO,    IF_EB("\033p", ESC_STR "p")},
  864.     {(int)KS_SE,    IF_EB("\033q", ESC_STR "q")},
  865.     {K_UP,        IF_EB("\033A", ESC_STR "A")},
  866.     {K_DOWN,        IF_EB("\033B", ESC_STR "B")},
  867.     {K_LEFT,        IF_EB("\033D", ESC_STR "D")},
  868.     {K_RIGHT,        IF_EB("\033C", ESC_STR "C")},
  869.     {K_S_UP,        IF_EB("\033a", ESC_STR "a")},
  870.     {K_S_DOWN,        IF_EB("\033b", ESC_STR "b")},
  871.     {K_S_LEFT,        IF_EB("\033d", ESC_STR "d")},
  872.     {K_S_RIGHT,        IF_EB("\033c", ESC_STR "c")},
  873.     {K_F1,        IF_EB("\033P", ESC_STR "P")},
  874.     {K_F2,        IF_EB("\033Q", ESC_STR "Q")},
  875.     {K_F3,        IF_EB("\033R", ESC_STR "R")},
  876.     {K_F4,        IF_EB("\033S", ESC_STR "S")},
  877.     {K_F5,        IF_EB("\033T", ESC_STR "T")},
  878.     {K_F6,        IF_EB("\033U", ESC_STR "U")},
  879.     {K_F7,        IF_EB("\033V", ESC_STR "V")},
  880.     {K_F8,        IF_EB("\033W", ESC_STR "W")},
  881.     {K_F9,        IF_EB("\033X", ESC_STR "X")},
  882.     {K_F10,        IF_EB("\033Y", ESC_STR "Y")},
  883.     {K_S_F1,        IF_EB("\033p", ESC_STR "p")},
  884.     {K_S_F2,        IF_EB("\033q", ESC_STR "q")},
  885.     {K_S_F3,        IF_EB("\033r", ESC_STR "r")},
  886.     {K_S_F4,        IF_EB("\033s", ESC_STR "s")},
  887.     {K_S_F5,        IF_EB("\033t", ESC_STR "t")},
  888.     {K_S_F6,        IF_EB("\033u", ESC_STR "u")},
  889.     {K_S_F7,        IF_EB("\033v", ESC_STR "v")},
  890.     {K_S_F8,        IF_EB("\033w", ESC_STR "w")},
  891.     {K_S_F9,        IF_EB("\033x", ESC_STR "x")},
  892.     {K_S_F10,        IF_EB("\033y", ESC_STR "y")},
  893.     {K_INS,        IF_EB("\033I", ESC_STR "I")},
  894.     {K_HOME,        IF_EB("\033E", ESC_STR "E")},
  895.     {K_PAGEDOWN,    IF_EB("\033b", ESC_STR "b")},
  896.     {K_PAGEUP,        IF_EB("\033a", ESC_STR "a")},
  897. #  else
  898.     {(int)KS_AL,    IF_EB("\033T", ESC_STR "T")},
  899.     {(int)KS_DL,    IF_EB("\033U", ESC_STR "U")},
  900.     {(int)KS_CL,    IF_EB("\033H\033J", ESC_STR "H" ESC_STR_nc "J")},
  901.     {(int)KS_ME,    IF_EB("\033SO", ESC_STR "SO")},
  902.     {(int)KS_MR,    IF_EB("\033S2", ESC_STR "S2")},
  903.     {(int)KS_MS,    "y"},
  904. #  endif
  905. # endif
  906.  
  907. # if defined(UNIX) || defined(ALL_BUILTIN_TCAPS) || defined(SOME_BUILTIN_TCAPS) || defined(__EMX__)
  908. /*
  909.  * The xterm termcap is missing F14 and F15, because they send the same
  910.  * codes as the undo and help key, although they don't work on all keyboards.
  911.  */
  912.     {(int)KS_NAME,    "xterm"},
  913.     {(int)KS_CE,    IF_EB("\033[K", ESC_STR "[K")},
  914.     {(int)KS_AL,    IF_EB("\033[L", ESC_STR "[L")},
  915. #  ifdef TERMINFO
  916.     {(int)KS_CAL,    IF_EB("\033[%p1%dL", ESC_STR "[%p1%dL")},
  917. #  else
  918.     {(int)KS_CAL,    IF_EB("\033[%dL", ESC_STR "[%dL")},
  919. #  endif
  920.     {(int)KS_DL,    IF_EB("\033[M", ESC_STR "[M")},
  921. #  ifdef TERMINFO
  922.     {(int)KS_CDL,    IF_EB("\033[%p1%dM", ESC_STR "[%p1%dM")},
  923. #  else
  924.     {(int)KS_CDL,    IF_EB("\033[%dM", ESC_STR "[%dM")},
  925. #  endif
  926. #  ifdef TERMINFO
  927.     {(int)KS_CS,    IF_EB("\033[%i%p1%d;%p2%dr",
  928.                           ESC_STR "[%i%p1%d;%p2%dr")},
  929. #  else
  930.     {(int)KS_CS,    IF_EB("\033[%i%d;%dr", ESC_STR "[%i%d;%dr")},
  931. #  endif
  932.     {(int)KS_CL,    IF_EB("\033[H\033[2J", ESC_STR "[H" ESC_STR_nc "[2J")},
  933.     {(int)KS_CD,    IF_EB("\033[J", ESC_STR "[J")},
  934.     {(int)KS_ME,    IF_EB("\033[m", ESC_STR "[m")},
  935.     {(int)KS_MR,    IF_EB("\033[7m", ESC_STR "[7m")},
  936.     {(int)KS_MD,    IF_EB("\033[1m", ESC_STR "[1m")},
  937.     {(int)KS_UE,    IF_EB("\033[m", ESC_STR "[m")},
  938.     {(int)KS_US,    IF_EB("\033[4m", ESC_STR "[4m")},
  939.     {(int)KS_MS,    "y"},
  940.     {(int)KS_UT,    "y"},
  941.     {(int)KS_LE,    "\010"},
  942. #  ifdef TERMINFO
  943.     {(int)KS_CM,    IF_EB("\033[%i%p1%d;%p2%dH",
  944.                           ESC_STR "[%i%p1%d;%p2%dH")},
  945. #  else
  946.     {(int)KS_CM,    IF_EB("\033[%i%d;%dH", ESC_STR "[%i%d;%dH")},
  947. #  endif
  948.     {(int)KS_SR,    IF_EB("\033M", ESC_STR "M")},
  949. #  ifdef TERMINFO
  950.     {(int)KS_CRI,    IF_EB("\033[%p1%dC", ESC_STR "[%p1%dC")},
  951. #  else
  952.     {(int)KS_CRI,    IF_EB("\033[%dC", ESC_STR "[%dC")},
  953. #  endif
  954.     {(int)KS_KS,    IF_EB("\033[?1h\033=", ESC_STR "[?1h" ESC_STR_nc "=")},
  955.     {(int)KS_KE,    IF_EB("\033[?1l\033>", ESC_STR "[?1l" ESC_STR_nc ">")},
  956. #  ifdef FEAT_XTERM_SAVE
  957.     {(int)KS_TI,    IF_EB("\0337\033[?47h", ESC_STR "7" ESC_STR_nc "[?47h")},
  958.     {(int)KS_TE,    IF_EB("\033[2J\033[?47l\0338",
  959.                   ESC_STR "[2J" ESC_STR_nc "[?47l" ESC_STR_nc "8")},
  960. #  endif
  961.     {(int)KS_CIS,    IF_EB("\033]1;", ESC_STR "]1;")},
  962.     {(int)KS_CIE,    "\007"},
  963.     {(int)KS_TS,    IF_EB("\033]2;", ESC_STR "]2;")},
  964.     {(int)KS_FS,    "\007"},
  965. #  ifdef TERMINFO
  966.     {(int)KS_CWS,    IF_EB("\033[8;%p1%d;%p2%dt",
  967.                           ESC_STR "[8;%p1%d;%p2%dt")},
  968.     {(int)KS_CWP,    IF_EB("\033[3;%p1%d;%p2%dt",
  969.                           ESC_STR "[3;%p1%d;%p2%dt")},
  970. #  else
  971.     {(int)KS_CWS,    IF_EB("\033[8;%d;%dt", ESC_STR "[8;%d;%dt")},
  972.     {(int)KS_CWP,    IF_EB("\033[3;%d;%dt", ESC_STR "[3;%d;%dt")},
  973. #  endif
  974.     {(int)KS_CRV,    IF_EB("\033[>c", ESC_STR "[>c")},
  975.     {K_UP,        IF_EB("\033OA", ESC_STR "OA")},
  976.     {K_DOWN,        IF_EB("\033OB", ESC_STR "OB")},
  977.     {K_RIGHT,        IF_EB("\033OC", ESC_STR "OC")},
  978.     {K_LEFT,        IF_EB("\033OD", ESC_STR "OD")},
  979.     {K_S_UP,        IF_EB("\033O2A", ESC_STR "O2A")},
  980.     {K_S_DOWN,        IF_EB("\033O2B", ESC_STR "O2B")},
  981.     {K_S_RIGHT,        IF_EB("\033O2C", ESC_STR "O2C")},
  982.     {K_C_RIGHT,        IF_EB("\033O5C", ESC_STR "O5C")},
  983.     {K_S_LEFT,        IF_EB("\033O2D", ESC_STR "O2D")},
  984.     {K_C_LEFT,        IF_EB("\033O5D", ESC_STR "O5D")},
  985.     /* An extra set of function keys for vt100 mode */
  986.     {K_XF1,        IF_EB("\033OP", ESC_STR "OP")},
  987.     {K_XF2,        IF_EB("\033OQ", ESC_STR "OQ")},
  988.     {K_XF3,        IF_EB("\033OR", ESC_STR "OR")},
  989.     {K_XF4,        IF_EB("\033OS", ESC_STR "OS")},
  990.     {K_F1,        IF_EB("\033[11~", ESC_STR "[11~")},
  991.     {K_F2,        IF_EB("\033[12~", ESC_STR "[12~")},
  992.     {K_F3,        IF_EB("\033[13~", ESC_STR "[13~")},
  993.     {K_F4,        IF_EB("\033[14~", ESC_STR "[14~")},
  994.     {K_F5,        IF_EB("\033[15~", ESC_STR "[15~")},
  995.     {K_F6,        IF_EB("\033[17~", ESC_STR "[17~")},
  996.     {K_F7,        IF_EB("\033[18~", ESC_STR "[18~")},
  997.     {K_F8,        IF_EB("\033[19~", ESC_STR "[19~")},
  998.     {K_F9,        IF_EB("\033[20~", ESC_STR "[20~")},
  999.     {K_F10,        IF_EB("\033[21~", ESC_STR "[21~")},
  1000.     {K_F11,        IF_EB("\033[23~", ESC_STR "[23~")},
  1001.     {K_F12,        IF_EB("\033[24~", ESC_STR "[24~")},
  1002.     {K_S_XF1,        IF_EB("\033O2P", ESC_STR "O2P")},
  1003.     {K_S_XF2,        IF_EB("\033O2Q", ESC_STR "O2Q")},
  1004.     {K_S_XF3,        IF_EB("\033O2R", ESC_STR "O2R")},
  1005.     {K_S_XF4,        IF_EB("\033O2S", ESC_STR "O2S")},
  1006.     {K_S_F1,        IF_EB("\033[11;2~", ESC_STR "[11;2~")},
  1007.     {K_S_F2,        IF_EB("\033[12;2~", ESC_STR "[12;2~")},
  1008.     {K_S_F3,        IF_EB("\033[13;2~", ESC_STR "[13;2~")},
  1009.     {K_S_F4,        IF_EB("\033[14;2~", ESC_STR "[14;2~")},
  1010.     {K_S_F5,        IF_EB("\033[15;2~", ESC_STR "[15;2~")},
  1011.     {K_S_F6,        IF_EB("\033[17;2~", ESC_STR "[17;2~")},
  1012.     {K_S_F7,        IF_EB("\033[18;2~", ESC_STR "[18;2~")},
  1013.     {K_S_F8,        IF_EB("\033[19;2~", ESC_STR "[19;2~")},
  1014.     {K_S_F9,        IF_EB("\033[20;2~", ESC_STR "[20;2~")},
  1015.     {K_S_F10,        IF_EB("\033[21;2~", ESC_STR "[21;2~")},
  1016.     {K_S_F11,        IF_EB("\033[23;2~", ESC_STR "[23;2~")},
  1017.     {K_S_F12,        IF_EB("\033[24;2~", ESC_STR "[24;2~")},
  1018.     {K_HELP,        IF_EB("\033[28~", ESC_STR "[28~")},
  1019.     {K_UNDO,        IF_EB("\033[26~", ESC_STR "[26~")},
  1020.     {K_INS,        IF_EB("\033[2~", ESC_STR "[2~")},
  1021.     {K_HOME,        IF_EB("\033[7~", ESC_STR "[7~")},
  1022.     {K_S_HOME,        IF_EB("\033O2H", ESC_STR "O2H")},
  1023.     {K_C_HOME,        IF_EB("\033O5H", ESC_STR "O5H")},
  1024.     {K_KHOME,        IF_EB("\033[1~", ESC_STR "[1~")},
  1025.     {K_XHOME,        IF_EB("\033OH", ESC_STR "OH")},    /* alternate Home */
  1026.     {K_END,        IF_EB("\033[8~", ESC_STR "[8~")},
  1027.     {K_S_END,        IF_EB("\033O2F", ESC_STR "O2F")},
  1028.     {K_C_END,        IF_EB("\033O5F", ESC_STR "O5F")},
  1029.     {K_KEND,        IF_EB("\033[4~", ESC_STR "[4~")},
  1030.     {K_XEND,        IF_EB("\033OF", ESC_STR "OF")},    /* alternate End */
  1031.     {K_PAGEUP,        IF_EB("\033[5~", ESC_STR "[5~")},
  1032.     {K_PAGEDOWN,    IF_EB("\033[6~", ESC_STR "[6~")},
  1033.     {K_KPLUS,        IF_EB("\033Ok", ESC_STR "Ok")},    /* keypad plus */
  1034.     {K_KMINUS,        IF_EB("\033Om", ESC_STR "Om")},    /* keypad minus */
  1035.     {K_KDIVIDE,        IF_EB("\033Oo", ESC_STR "Oo")},    /* keypad / */
  1036.     {K_KMULTIPLY,    IF_EB("\033Oj", ESC_STR "Oj")},    /* keypad * */
  1037.     {K_KENTER,        IF_EB("\033OM", ESC_STR "OM")},    /* keypad Enter */
  1038.     {K_KDEL,        IF_EB("\033[3~", ESC_STR "[3~")},    /* keypad Del */
  1039.  
  1040.     {BT_EXTRA_KEYS,   ""},
  1041.     {TERMCAP2KEY('k', '0'), IF_EB("\033[10~", ESC_STR "[10~")},    /* F0 */
  1042.     {TERMCAP2KEY('F', '3'), IF_EB("\033[25~", ESC_STR "[25~")},    /* F13 */
  1043.     {TERMCAP2KEY('F', '6'), IF_EB("\033[29~", ESC_STR "[29~")},    /* F16 */
  1044.     {TERMCAP2KEY('F', '7'), IF_EB("\033[31~", ESC_STR "[31~")},    /* F17 */
  1045.     {TERMCAP2KEY('F', '8'), IF_EB("\033[32~", ESC_STR "[32~")},    /* F18 */
  1046.     {TERMCAP2KEY('F', '9'), IF_EB("\033[33~", ESC_STR "[33~")},    /* F19 */
  1047.     {TERMCAP2KEY('F', 'A'), IF_EB("\033[34~", ESC_STR "[34~")},    /* F20 */
  1048. # endif
  1049.  
  1050. # if defined(UNIX) || defined(ALL_BUILTIN_TCAPS)
  1051. /*
  1052.  * iris-ansi for Silicon Graphics machines.
  1053.  */
  1054.     {(int)KS_NAME,    "iris-ansi"},
  1055.     {(int)KS_CE,    "\033[K"},
  1056.     {(int)KS_CD,    "\033[J"},
  1057.     {(int)KS_AL,    "\033[L"},
  1058. #  ifdef TERMINFO
  1059.     {(int)KS_CAL,    "\033[%p1%dL"},
  1060. #  else
  1061.     {(int)KS_CAL,    "\033[%dL"},
  1062. #  endif
  1063.     {(int)KS_DL,    "\033[M"},
  1064. #  ifdef TERMINFO
  1065.     {(int)KS_CDL,    "\033[%p1%dM"},
  1066. #  else
  1067.     {(int)KS_CDL,    "\033[%dM"},
  1068. #  endif
  1069. #if 0    /* The scroll region is not working as Vim expects. */
  1070. #  ifdef TERMINFO
  1071.     {(int)KS_CS,    "\033[%i%p1%d;%p2%dr"},
  1072. #  else
  1073.     {(int)KS_CS,    "\033[%i%d;%dr"},
  1074. #  endif
  1075. #endif
  1076.     {(int)KS_CL,    "\033[H\033[2J"},
  1077.     {(int)KS_VE,    "\033[9/y\033[12/y"},
  1078.     {(int)KS_VS,    "\033[10/y\033[=1h\033[=2l"},
  1079.     {(int)KS_TI,    "\033[=6h"},
  1080.     {(int)KS_TE,    "\033[=6l"},
  1081.     {(int)KS_SE,    "\033[m"},
  1082.     {(int)KS_SO,    "\033[1;7m"},
  1083.     {(int)KS_ME,    "\033[m"},
  1084.     {(int)KS_MR,    "\033[7m"},
  1085.     {(int)KS_MD,    "\033[1m"},
  1086.     {(int)KS_UE,    "\033[m"},
  1087.     {(int)KS_CCO,    "8"},            /* allow 8 colors */
  1088. #  ifdef TERMINFO
  1089.     {(int)KS_CAB,    "\033[4%p1%dm"},    /* set background color */
  1090.     {(int)KS_CAF,    "\033[3%p1%dm"},    /* set foreground color */
  1091. #  else
  1092.     {(int)KS_CAB,    "\033[4%dm"},        /* set background color */
  1093.     {(int)KS_CAF,    "\033[3%dm"},        /* set foreground color */
  1094. #  endif
  1095.     {(int)KS_US,    "\033[4m"},
  1096.     {(int)KS_MS,    "y"},        /* guessed */
  1097.     {(int)KS_UT,    "y"},        /* guessed */
  1098.     {(int)KS_LE,    "\010"},
  1099. #  ifdef TERMINFO
  1100.     {(int)KS_CM,    "\033[%i%p1%d;%p2%dH"},
  1101. #  else
  1102.     {(int)KS_CM,    "\033[%i%d;%dH"},
  1103. #  endif
  1104.     {(int)KS_SR,    "\033M"},
  1105. #  ifdef TERMINFO
  1106.     {(int)KS_CRI,    "\033[%p1%dC"},
  1107. #  else
  1108.     {(int)KS_CRI,    "\033[%dC"},
  1109. #  endif
  1110.     {(int)KS_CIS,    "\033P3.y"},
  1111.     {(int)KS_CIE,    "\234"},
  1112.     {(int)KS_TS,    "\033P1.y"},
  1113.     {(int)KS_FS,    "\234"},
  1114. #  ifdef TERMINFO
  1115.     {(int)KS_CWS,    "\033[203;%p1%d;%p2%d/y"},
  1116. #  else
  1117.     {(int)KS_CWS,    "\033[203;%d;%d/y"},
  1118. #  endif
  1119.     {K_UP,        "\033[A"},
  1120.     {K_DOWN,        "\033[B"},
  1121.     {K_LEFT,        "\033[D"},
  1122.     {K_RIGHT,        "\033[C"},
  1123.     {K_S_UP,        "\033[161q"},
  1124.     {K_S_DOWN,        "\033[164q"},
  1125.     {K_S_LEFT,        "\033[158q"},
  1126.     {K_S_RIGHT,        "\033[167q"},
  1127.     {K_F1,        "\033[001q"},
  1128.     {K_F2,        "\033[002q"},
  1129.     {K_F3,        "\033[003q"},
  1130.     {K_F4,        "\033[004q"},
  1131.     {K_F5,        "\033[005q"},
  1132.     {K_F6,        "\033[006q"},
  1133.     {K_F7,        "\033[007q"},
  1134.     {K_F8,        "\033[008q"},
  1135.     {K_F9,        "\033[009q"},
  1136.     {K_F10,        "\033[010q"},
  1137.     {K_F11,        "\033[011q"},
  1138.     {K_F12,        "\033[012q"},
  1139.     {K_S_F1,        "\033[013q"},
  1140.     {K_S_F2,        "\033[014q"},
  1141.     {K_S_F3,        "\033[015q"},
  1142.     {K_S_F4,        "\033[016q"},
  1143.     {K_S_F5,        "\033[017q"},
  1144.     {K_S_F6,        "\033[018q"},
  1145.     {K_S_F7,        "\033[019q"},
  1146.     {K_S_F8,        "\033[020q"},
  1147.     {K_S_F9,        "\033[021q"},
  1148.     {K_S_F10,        "\033[022q"},
  1149.     {K_S_F11,        "\033[023q"},
  1150.     {K_S_F12,        "\033[024q"},
  1151.     {K_INS,        "\033[139q"},
  1152.     {K_HOME,        "\033[H"},
  1153.     {K_END,        "\033[146q"},
  1154.     {K_PAGEUP,        "\033[150q"},
  1155.     {K_PAGEDOWN,    "\033[154q"},
  1156. # endif
  1157.  
  1158. # if defined(DEBUG) || defined(ALL_BUILTIN_TCAPS)
  1159. /*
  1160.  * for debugging
  1161.  */
  1162.     {(int)KS_NAME,    "debug"},
  1163.     {(int)KS_CE,    "[CE]"},
  1164.     {(int)KS_CD,    "[CD]"},
  1165.     {(int)KS_AL,    "[AL]"},
  1166. #  ifdef TERMINFO
  1167.     {(int)KS_CAL,    "[CAL%p1%d]"},
  1168. #  else
  1169.     {(int)KS_CAL,    "[CAL%d]"},
  1170. #  endif
  1171.     {(int)KS_DL,    "[DL]"},
  1172. #  ifdef TERMINFO
  1173.     {(int)KS_CDL,    "[CDL%p1%d]"},
  1174. #  else
  1175.     {(int)KS_CDL,    "[CDL%d]"},
  1176. #  endif
  1177. #  ifdef TERMINFO
  1178.     {(int)KS_CS,    "[%p1%dCS%p2%d]"},
  1179. #  else
  1180.     {(int)KS_CS,    "[%dCS%d]"},
  1181. #  endif
  1182. #  ifdef FEAT_VERTSPLIT
  1183. #   ifdef TERMINFO
  1184.     {(int)KS_CSV,    "[%p1%dCSV%p2%d]"},
  1185. #   else
  1186.     {(int)KS_CSV,    "[%dCSV%d]"},
  1187. #   endif
  1188. #  endif
  1189. #  ifdef TERMINFO
  1190.     {(int)KS_CAB,    "[CAB%p1%d]"},
  1191.     {(int)KS_CAF,    "[CAF%p1%d]"},
  1192.     {(int)KS_CSB,    "[CSB%p1%d]"},
  1193.     {(int)KS_CSF,    "[CSF%p1%d]"},
  1194. #  else
  1195.     {(int)KS_CAB,    "[CAB%d]"},
  1196.     {(int)KS_CAF,    "[CAF%d]"},
  1197.     {(int)KS_CSB,    "[CSB%d]"},
  1198.     {(int)KS_CSF,    "[CSF%d]"},
  1199. #  endif
  1200.     {(int)KS_OP,    "[OP]"},
  1201.     {(int)KS_LE,    "[LE]"},
  1202.     {(int)KS_CL,    "[CL]"},
  1203.     {(int)KS_VI,    "[VI]"},
  1204.     {(int)KS_VE,    "[VE]"},
  1205.     {(int)KS_VS,    "[VS]"},
  1206.     {(int)KS_ME,    "[ME]"},
  1207.     {(int)KS_MR,    "[MR]"},
  1208.     {(int)KS_MB,    "[MB]"},
  1209.     {(int)KS_MD,    "[MD]"},
  1210.     {(int)KS_SE,    "[SE]"},
  1211.     {(int)KS_SO,    "[SO]"},
  1212.     {(int)KS_UE,    "[UE]"},
  1213.     {(int)KS_US,    "[US]"},
  1214.     {(int)KS_MS,    "[MS]"},
  1215.     {(int)KS_UT,    "[UT]"},
  1216. #  ifdef TERMINFO
  1217.     {(int)KS_CM,    "[%p1%dCM%p2%d]"},
  1218. #  else
  1219.     {(int)KS_CM,    "[%dCM%d]"},
  1220. #  endif
  1221.     {(int)KS_SR,    "[SR]"},
  1222. #  ifdef TERMINFO
  1223.     {(int)KS_CRI,    "[CRI%p1%d]"},
  1224. #  else
  1225.     {(int)KS_CRI,    "[CRI%d]"},
  1226. #  endif
  1227.     {(int)KS_VB,    "[VB]"},
  1228.     {(int)KS_KS,    "[KS]"},
  1229.     {(int)KS_KE,    "[KE]"},
  1230.     {(int)KS_TI,    "[TI]"},
  1231.     {(int)KS_TE,    "[TE]"},
  1232.     {(int)KS_CIS,    "[CIS]"},
  1233.     {(int)KS_CIE,    "[CIE]"},
  1234.     {(int)KS_TS,    "[TS]"},
  1235.     {(int)KS_FS,    "[FS]"},
  1236. #  ifdef TERMINFO
  1237.     {(int)KS_CWS,    "[%p1%dCWS%p2%d]"},
  1238.     {(int)KS_CWP,    "[%p1%dCWP%p2%d]"},
  1239. #  else
  1240.     {(int)KS_CWS,    "[%dCWS%d]"},
  1241.     {(int)KS_CWP,    "[%dCWP%d]"},
  1242. #  endif
  1243.     {(int)KS_CRV,    "[CRV]"},
  1244.     {K_UP,        "[KU]"},
  1245.     {K_DOWN,        "[KD]"},
  1246.     {K_LEFT,        "[KL]"},
  1247.     {K_RIGHT,        "[KR]"},
  1248.     {K_S_UP,        "[S-KU]"},
  1249.     {K_S_DOWN,        "[S-KD]"},
  1250.     {K_S_LEFT,        "[S-KL]"},
  1251.     {K_C_LEFT,        "[C-KL]"},
  1252.     {K_S_RIGHT,        "[S-KR]"},
  1253.     {K_C_RIGHT,        "[C-KR]"},
  1254.     {K_F1,        "[F1]"},
  1255.     {K_XF1,        "[xF1]"},
  1256.     {K_F2,        "[F2]"},
  1257.     {K_XF2,        "[xF2]"},
  1258.     {K_F3,        "[F3]"},
  1259.     {K_XF3,        "[xF3]"},
  1260.     {K_F4,        "[F4]"},
  1261.     {K_XF4,        "[xF4]"},
  1262.     {K_F5,        "[F5]"},
  1263.     {K_F6,        "[F6]"},
  1264.     {K_F7,        "[F7]"},
  1265.     {K_F8,        "[F8]"},
  1266.     {K_F9,        "[F9]"},
  1267.     {K_F10,        "[F10]"},
  1268.     {K_F11,        "[F11]"},
  1269.     {K_F12,        "[F12]"},
  1270.     {K_S_F1,        "[S-F1]"},
  1271.     {K_S_XF1,        "[S-xF1]"},
  1272.     {K_S_F2,        "[S-F2]"},
  1273.     {K_S_XF2,        "[S-xF2]"},
  1274.     {K_S_F3,        "[S-F3]"},
  1275.     {K_S_XF3,        "[S-xF3]"},
  1276.     {K_S_F4,        "[S-F4]"},
  1277.     {K_S_XF4,        "[S-xF4]"},
  1278.     {K_S_F5,        "[S-F5]"},
  1279.     {K_S_F6,        "[S-F6]"},
  1280.     {K_S_F7,        "[S-F7]"},
  1281.     {K_S_F8,        "[S-F8]"},
  1282.     {K_S_F9,        "[S-F9]"},
  1283.     {K_S_F10,        "[S-F10]"},
  1284.     {K_S_F11,        "[S-F11]"},
  1285.     {K_S_F12,        "[S-F12]"},
  1286.     {K_HELP,        "[HELP]"},
  1287.     {K_UNDO,        "[UNDO]"},
  1288.     {K_BS,        "[BS]"},
  1289.     {K_INS,        "[INS]"},
  1290.     {K_KINS,        "[KINS]"},
  1291.     {K_DEL,        "[DEL]"},
  1292.     {K_KDEL,        "[KDEL]"},
  1293.     {K_HOME,        "[HOME]"},
  1294.     {K_S_HOME,        "[C-HOME]"},
  1295.     {K_C_HOME,        "[C-HOME]"},
  1296.     {K_KHOME,        "[KHOME]"},
  1297.     {K_XHOME,        "[XHOME]"},
  1298.     {K_END,        "[END]"},
  1299.     {K_S_END,        "[C-END]"},
  1300.     {K_C_END,        "[C-END]"},
  1301.     {K_KEND,        "[KEND]"},
  1302.     {K_XEND,        "[XEND]"},
  1303.     {K_PAGEUP,        "[PAGEUP]"},
  1304.     {K_PAGEDOWN,    "[PAGEDOWN]"},
  1305.     {K_KPAGEUP,        "[KPAGEUP]"},
  1306.     {K_KPAGEDOWN,    "[KPAGEDOWN]"},
  1307.     {K_MOUSE,        "[MOUSE]"},
  1308.     {K_KPLUS,        "[KPLUS]"},
  1309.     {K_KMINUS,        "[KMINUS]"},
  1310.     {K_KDIVIDE,        "[KDIVIDE]"},
  1311.     {K_KMULTIPLY,    "[KMULTIPLY]"},
  1312.     {K_KENTER,        "[KENTER]"},
  1313.     {K_KPOINT,        "[KPOINT]"},
  1314.     {K_K0,        "[K0]"},
  1315.     {K_K1,        "[K1]"},
  1316.     {K_K2,        "[K2]"},
  1317.     {K_K3,        "[K3]"},
  1318.     {K_K4,        "[K4]"},
  1319.     {K_K5,        "[K5]"},
  1320.     {K_K6,        "[K6]"},
  1321.     {K_K7,        "[K7]"},
  1322.     {K_K8,        "[K8]"},
  1323.     {K_K9,        "[K9]"},
  1324. # endif
  1325.  
  1326. #endif /* NO_BUILTIN_TCAPS */
  1327.  
  1328. /*
  1329.  * The most minimal terminal: only clear screen and cursor positioning
  1330.  * Always included.
  1331.  */
  1332.     {(int)KS_NAME,    "dumb"},
  1333.     {(int)KS_CL,    "\014"},
  1334. #ifdef TERMINFO
  1335.     {(int)KS_CM,    IF_EB("\033[%i%p1%d;%p2%dH",
  1336.                           ESC_STR "[%i%p1%d;%p2%dH")},
  1337. #else
  1338.     {(int)KS_CM,    IF_EB("\033[%i%d;%dH", ESC_STR "[%i%d;%dH")},
  1339. #endif
  1340.  
  1341. /*
  1342.  * end marker
  1343.  */
  1344.     {(int)KS_NAME,    NULL}
  1345.  
  1346. };    /* end of builtin_termcaps */
  1347.  
  1348. /*
  1349.  * DEFAULT_TERM is used, when no terminal is specified with -T option or $TERM.
  1350.  */
  1351. #ifdef RISCOS
  1352. # define DEFAULT_TERM    (char_u *)"riscos"
  1353. #endif
  1354.  
  1355. #ifdef AMIGA
  1356. # define DEFAULT_TERM    (char_u *)"amiga"
  1357. #endif
  1358.  
  1359. #ifdef MSWIN
  1360. # define DEFAULT_TERM    (char_u *)"win32"
  1361. #endif
  1362.  
  1363. #ifdef MSDOS
  1364. # define DEFAULT_TERM    (char_u *)"pcterm"
  1365. #endif
  1366.  
  1367. #if defined(UNIX) && !defined(__MINT__)
  1368. # define DEFAULT_TERM    (char_u *)"ansi"
  1369. #endif
  1370.  
  1371. #ifdef __MINT__
  1372. # define DEFAULT_TERM    (char_u *)"vt52"
  1373. #endif
  1374.  
  1375. #ifdef __EMX__
  1376. # define DEFAULT_TERM    (char_u *)"os2ansi"
  1377. #endif
  1378.  
  1379. #ifdef VMS
  1380. # define DEFAULT_TERM    (char_u *)"vt320"
  1381. #endif
  1382.  
  1383. #ifdef __BEOS__
  1384. # undef DEFAULT_TERM
  1385. # define DEFAULT_TERM    (char_u *)"beos-ansi"
  1386. #endif
  1387.  
  1388. #if defined(MACOS)
  1389. # define DEFAULT_TERM    (char_u *)"mac-ansi"
  1390. #endif
  1391.  
  1392. /*
  1393.  * Term_strings contains currently used terminal output strings.
  1394.  * It is initialized with the default values by parse_builtin_tcap().
  1395.  * The values can be changed by setting the option with the same name.
  1396.  */
  1397. char_u *(term_strings[(int)KS_LAST + 1]);
  1398.  
  1399. static int    need_gather = FALSE;        /* need to fill termleader[] */
  1400. static char_u    termleader[256 + 1];        /* for check_termcode() */
  1401. #ifdef FEAT_TERMRESPONSE
  1402. static int    check_for_codes = FALSE;    /* check for key code reponse */
  1403. #endif
  1404.  
  1405.     static struct builtin_term *
  1406. find_builtin_term(term)
  1407.     char_u    *term;
  1408. {
  1409.     struct builtin_term *p;
  1410.  
  1411.     p = builtin_termcaps;
  1412.     while (p->bt_string != NULL)
  1413.     {
  1414.     if (p->bt_entry == (int)KS_NAME)
  1415.     {
  1416. #ifdef UNIX
  1417.         if (STRCMP(p->bt_string, "iris-ansi") == 0 && vim_is_iris(term))
  1418.         return p;
  1419.         else if (STRCMP(p->bt_string, "xterm") == 0 && vim_is_xterm(term))
  1420.         return p;
  1421.         else
  1422. #endif
  1423. #ifdef VMS
  1424.         if (STRCMP(p->bt_string, "vt320") == 0 && vim_is_vt300(term))
  1425.             return p;
  1426.         else
  1427. #endif
  1428.           if (STRCMP(term, p->bt_string) == 0)
  1429.             return p;
  1430.     }
  1431.     ++p;
  1432.     }
  1433.     return p;
  1434. }
  1435.  
  1436. /*
  1437.  * Parsing of the builtin termcap entries.
  1438.  * Caller should check if 'name' is a valid builtin term.
  1439.  * The terminal's name is not set, as this is already done in termcapinit().
  1440.  */
  1441.     static void
  1442. parse_builtin_tcap(term)
  1443.     char_u  *term;
  1444. {
  1445.     struct builtin_term        *p;
  1446.     char_u            name[2];
  1447.     int                term_8bit;
  1448.  
  1449.     p = find_builtin_term(term);
  1450.     term_8bit = term_is_8bit(term);
  1451.  
  1452.     for (++p; p->bt_entry != (int)KS_NAME && p->bt_entry != BT_EXTRA_KEYS; ++p)
  1453.     {
  1454.     if ((int)p->bt_entry >= 0)    /* KS_xx entry */
  1455.     {
  1456.         /* Only set the value if it wasn't set yet. */
  1457.         if (term_strings[p->bt_entry] == NULL
  1458.                  || term_strings[p->bt_entry] == empty_option)
  1459.         {
  1460.         /* 8bit terminal: use CSI instead of <Esc>[ */
  1461.         if (term_8bit && term_7to8bit((char_u *)p->bt_string) != 0)
  1462.         {
  1463.             char_u  *s, *t;
  1464.  
  1465.             s = vim_strsave((char_u *)p->bt_string);
  1466.             if (s != NULL)
  1467.             {
  1468.             for (t = s; *t; ++t)
  1469.                 if (term_7to8bit(t))
  1470.                 {
  1471.                 *t = term_7to8bit(t);
  1472.                 STRCPY(t + 1, t + 2);
  1473.                 }
  1474.             term_strings[p->bt_entry] = s;
  1475.             set_term_option_alloced(&term_strings[p->bt_entry]);
  1476.             }
  1477.         }
  1478.         else
  1479.             term_strings[p->bt_entry] = (char_u *)p->bt_string;
  1480.         }
  1481.     }
  1482.     else
  1483.     {
  1484.         name[0] = KEY2TERMCAP0((int)p->bt_entry);
  1485.         name[1] = KEY2TERMCAP1((int)p->bt_entry);
  1486.         if (find_termcode(name) == NULL)
  1487.         add_termcode(name, (char_u *)p->bt_string, term_8bit);
  1488.     }
  1489.     }
  1490. }
  1491. #if defined(HAVE_TGETENT) || defined(FEAT_TERMRESPONSE)
  1492. static void set_color_count __ARGS((int nr));
  1493.  
  1494. /*
  1495.  * Set number of colors.
  1496.  * Store it as a number in t_colors.
  1497.  * Store it as a string in T_CCO (using nr_colors[]).
  1498.  */
  1499.     static void
  1500. set_color_count(nr)
  1501.     int        nr;
  1502. {
  1503.     char_u    nr_colors[20];        /* string for number of colors */
  1504.  
  1505.     t_colors = nr;
  1506.     if (t_colors > 1)
  1507.     sprintf((char *)nr_colors, "%d", t_colors);
  1508.     else
  1509.     *nr_colors = NUL;
  1510.     set_string_option_direct((char_u *)"t_Co", -1, nr_colors, OPT_FREE);
  1511. }
  1512. #endif
  1513.  
  1514. #ifdef HAVE_TGETENT
  1515. static char *(key_names[]) =
  1516. {
  1517. #ifdef FEAT_TERMRESPONSE
  1518.     /* Do this one first, it may cause a screen redraw. */
  1519.     "Co",
  1520. #endif
  1521.     "ku", "kd", "kr", "kl",
  1522. # ifdef ARCHIE
  1523.     "su", "sd",        /* Termcap code made up! */
  1524. # endif
  1525.     "#2", "#4", "%i", "*7",
  1526.     "k1", "k2", "k3", "k4", "k5", "k6",
  1527.     "k7", "k8", "k9", "k;", "F1", "F2",
  1528.     "%1", "&8", "kb", "kI", "kD", "kh",
  1529.     "@7", "kP", "kN", "K1", "K3", "K4", "K5",
  1530.     NULL
  1531. };
  1532. #endif
  1533.  
  1534. /*
  1535.  * Set terminal options for terminal "term".
  1536.  * Return OK if terminal 'term' was found in a termcap, FAIL otherwise.
  1537.  *
  1538.  * While doing this, until ttest(), some options may be NULL, be careful.
  1539.  */
  1540.     int
  1541. set_termname(term)
  1542.     char_u *term;
  1543. {
  1544.     struct builtin_term *termp;
  1545. #ifdef HAVE_TGETENT
  1546.     int        builtin_first = p_tbi;
  1547.     int        try;
  1548.     int        termcap_cleared = FALSE;
  1549. #endif
  1550.     int        width = 0, height = 0;
  1551.     char_u    *error_msg = NULL;
  1552.     char_u    *bs_p, *del_p;
  1553.  
  1554.     detected_8bit = FALSE;        /* reset 8-bit detection */
  1555.  
  1556.     if (term_is_builtin(term))
  1557.     {
  1558.     term += 8;
  1559. #ifdef HAVE_TGETENT
  1560.     builtin_first = 1;
  1561. #endif
  1562.     }
  1563.  
  1564. /*
  1565.  * If HAVE_TGETENT is not defined, only the builtin termcap is used, otherwise:
  1566.  *   If builtin_first is TRUE:
  1567.  *     0. try builtin termcap
  1568.  *     1. try external termcap
  1569.  *     2. if both fail default to a builtin terminal
  1570.  *   If builtin_first is FALSE:
  1571.  *     1. try external termcap
  1572.  *     2. try builtin termcap, if both fail default to a builtin terminal
  1573.  */
  1574. #ifdef HAVE_TGETENT
  1575.     for (try = builtin_first ? 0 : 1; try < 3; ++try)
  1576.     {
  1577.     /*
  1578.      * Use external termcap
  1579.      */
  1580.     if (try == 1)
  1581.     {
  1582.         char_u        *p;
  1583.         static char_u   tstrbuf[TBUFSZ];
  1584.         int            i;
  1585.         char_u        tbuf[TBUFSZ];
  1586.         char_u        *tp;
  1587.         static struct {
  1588.                 enum SpecialKey dest; /* index in term_strings[] */
  1589.                 char *name;          /* termcap name for string */
  1590.               } string_names[] =
  1591.                 {    {KS_CE, "ce"}, {KS_AL, "al"}, {KS_CAL,"AL"},
  1592.                 {KS_DL, "dl"}, {KS_CDL,"DL"}, {KS_CS, "cs"},
  1593.                 {KS_CL, "cl"}, {KS_CD, "cd"},
  1594.                 {KS_VI, "vi"}, {KS_VE, "ve"}, {KS_MB, "mb"},
  1595.                 {KS_VS, "vs"}, {KS_ME, "me"}, {KS_MR, "mr"},
  1596.                 {KS_MD, "md"}, {KS_SE, "se"}, {KS_SO, "so"},
  1597.                 {KS_CZH,"ZH"}, {KS_CZR,"ZR"}, {KS_UE, "ue"},
  1598.                 {KS_US, "us"}, {KS_CM, "cm"}, {KS_SR, "sr"},
  1599.                 {KS_CRI,"RI"}, {KS_VB, "vb"}, {KS_KS, "ks"},
  1600.                 {KS_KE, "ke"}, {KS_TI, "ti"}, {KS_TE, "te"},
  1601.                 {KS_BC, "bc"}, {KS_CSB,"Sb"}, {KS_CSF,"Sf"},
  1602.                 {KS_CAB,"AB"}, {KS_CAF,"AF"}, {KS_LE, "le"},
  1603.                 {KS_ND, "nd"}, {KS_OP, "op"}, {KS_CRV, "RV"},
  1604.                 {KS_CIS, "IS"}, {KS_CIE, "IE"},
  1605.                 {KS_TS, "ts"}, {KS_FS, "fs"},
  1606.                 {KS_CWP, "WP"}, {KS_CWS, "WS"},
  1607.                 {(enum SpecialKey)0, NULL}
  1608.                 };
  1609.  
  1610.         /*
  1611.          * If the external termcap does not have a matching entry, try the
  1612.          * builtin ones.
  1613.          */
  1614.         if ((error_msg = tgetent_error(tbuf, term)) == NULL)
  1615.         {
  1616.         tp = tstrbuf;
  1617.         if (!termcap_cleared)
  1618.         {
  1619.             clear_termoptions();    /* clear old options */
  1620.             termcap_cleared = TRUE;
  1621.         }
  1622.  
  1623.         /* get output strings */
  1624.         for (i = 0; string_names[i].name != NULL; ++i)
  1625.         {
  1626.             if (term_str(string_names[i].dest) == NULL
  1627.                 || term_str(string_names[i].dest) == empty_option)
  1628.             term_str(string_names[i].dest) =
  1629.                        TGETSTR(string_names[i].name, &tp);
  1630.         }
  1631.  
  1632.         if ((T_MS == NULL || T_MS == empty_option) && tgetflag("ms"))
  1633.             T_MS = (char_u *)"y";
  1634.         if ((T_XS == NULL || T_XS == empty_option) && tgetflag("xs"))
  1635.             T_XS = (char_u *)"y";
  1636.         if ((T_DB == NULL || T_DB == empty_option) && tgetflag("db"))
  1637.             T_DB = (char_u *)"y";
  1638.         if ((T_DA == NULL || T_DA == empty_option) && tgetflag("da"))
  1639.             T_DA = (char_u *)"y";
  1640.         if ((T_UT == NULL || T_UT == empty_option) && tgetflag("ut"))
  1641.             T_UT = (char_u *)"y";
  1642.  
  1643.  
  1644.         /*
  1645.          * get key codes
  1646.          */
  1647.         for (i = 0; key_names[i] != NULL; ++i)
  1648.         {
  1649.             if (find_termcode((char_u *)key_names[i]) == NULL)
  1650.             {
  1651.             p = TGETSTR(key_names[i], &tp);
  1652.             /* if cursor-left == backspace, ignore it (televideo
  1653.              * 925) */
  1654.             if (p != NULL
  1655.                 && (*p != Ctrl_H
  1656.                     || key_names[i][0] != 'k'
  1657.                     || key_names[i][1] != 'l'))
  1658.                 add_termcode((char_u *)key_names[i], p, FALSE);
  1659.             }
  1660.         }
  1661.  
  1662.         if (height == 0)
  1663.             height = tgetnum("li");
  1664.         if (width == 0)
  1665.             width = tgetnum("co");
  1666.  
  1667.         /*
  1668.          * Get number of colors.
  1669.          */
  1670.         set_color_count(tgetnum("Co"));
  1671.  
  1672. # ifndef hpux
  1673.         BC = (char *)TGETSTR("bc", &tp);
  1674.         UP = (char *)TGETSTR("up", &tp);
  1675.         p = TGETSTR("pc", &tp);
  1676.         if (p)
  1677.             PC = *p;
  1678. # endif /* hpux */
  1679.         }
  1680.     }
  1681.     else        /* try == 0 || try == 2 */
  1682. #endif /* HAVE_TGETENT */
  1683.     /*
  1684.      * Use builtin termcap
  1685.      */
  1686.     {
  1687. #ifdef HAVE_TGETENT
  1688.         /*
  1689.          * If builtin termcap was already used, there is no need to search
  1690.          * for the builtin termcap again, quit now.
  1691.          */
  1692.         if (try == 2 && builtin_first && termcap_cleared)
  1693.         break;
  1694. #endif
  1695.         /*
  1696.          * search for 'term' in builtin_termcaps[]
  1697.          */
  1698.         termp = find_builtin_term(term);
  1699.         if (termp->bt_string == NULL)    /* did not find it */
  1700.         {
  1701. #ifdef HAVE_TGETENT
  1702.         /*
  1703.          * If try == 0, first try the external termcap. If that is not
  1704.          * found we'll get back here with try == 2.
  1705.          * If termcap_cleared is set we used the external termcap,
  1706.          * don't complain about not finding the term in the builtin
  1707.          * termcap.
  1708.          */
  1709.         if (try == 0)            /* try external one */
  1710.             continue;
  1711.         if (termcap_cleared)        /* found in external termcap */
  1712.             break;
  1713. #endif
  1714.  
  1715.         mch_errmsg("\r\n");
  1716.         if (error_msg != NULL)
  1717.         {
  1718.             mch_errmsg((char *)error_msg);
  1719.             mch_errmsg("\r\n");
  1720.         }
  1721.         mch_errmsg("'");
  1722.         mch_errmsg((char *)term);
  1723.         mch_errmsg(_("' not known. Available builtin terminals are:"));
  1724.         mch_errmsg("\r\n");
  1725.         for (termp = &(builtin_termcaps[0]); termp->bt_string != NULL;
  1726.                                       ++termp)
  1727.         {
  1728.             if (termp->bt_entry == (int)KS_NAME)
  1729.             {
  1730. #ifdef HAVE_TGETENT
  1731.             mch_errmsg("    builtin_");
  1732. #else
  1733.             mch_errmsg("    ");
  1734. #endif
  1735.             mch_errmsg(termp->bt_string);
  1736.             mch_errmsg("\r\n");
  1737.             }
  1738.         }
  1739.         /* when user typed :set term=xxx, quit here */
  1740.         if (starting != NO_SCREEN)
  1741.         {
  1742.             screen_start();    /* don't know where cursor is now */
  1743.             wait_return(TRUE);
  1744.             return FAIL;
  1745.         }
  1746.         term = DEFAULT_TERM;
  1747.         mch_errmsg(_("defaulting to '"));
  1748.         mch_errmsg((char *)term);
  1749.         mch_errmsg("'\r\n");
  1750.         if (emsg_silent == 0)
  1751.         {
  1752.             screen_start();    /* don't know where cursor is now */
  1753.             out_flush();
  1754.             ui_delay(2000L, TRUE);
  1755.         }
  1756.         set_string_option_direct((char_u *)"term", -1, term, OPT_FREE);
  1757.         display_errors();
  1758.         }
  1759.         out_flush();
  1760. #ifdef HAVE_TGETENT
  1761.         if (!termcap_cleared)
  1762.         {
  1763. #endif
  1764.         clear_termoptions();        /* clear old options */
  1765. #ifdef HAVE_TGETENT
  1766.         termcap_cleared = TRUE;
  1767.         }
  1768. #endif
  1769.         parse_builtin_tcap(term);
  1770. #ifdef FEAT_GUI
  1771.         if (term_is_gui(term))
  1772.         {
  1773.         out_flush();
  1774.         gui_init();
  1775.         /* If starting the GUI failed, don't do any of the other
  1776.          * things for this terminal */
  1777.         if (!gui.in_use)
  1778.             return FAIL;
  1779. #ifdef HAVE_TGETENT
  1780.         break;        /* don't try using external termcap */
  1781. #endif
  1782.         }
  1783. #endif /* FEAT_GUI */
  1784.     }
  1785. #ifdef HAVE_TGETENT
  1786.     }
  1787. #endif
  1788.  
  1789. /*
  1790.  * special: There is no info in the termcap about whether the cursor
  1791.  * positioning is relative to the start of the screen or to the start of the
  1792.  * scrolling region.  We just guess here. Only msdos pcterm is known to do it
  1793.  * relative.
  1794.  */
  1795.     if (STRCMP(term, "pcterm") == 0)
  1796.     T_CCS = (char_u *)"yes";
  1797.     else
  1798.     T_CCS = empty_option;
  1799.  
  1800. #ifdef UNIX
  1801. /*
  1802.  * Any "stty" settings override the default for t_kb from the termcap.
  1803.  * This is in os_unix.c, because it depends a lot on the version of unix that
  1804.  * is being used.
  1805.  * Don't do this when the GUI is active, it uses "t_kb" and "t_kD" directly.
  1806.  */
  1807. #ifdef FEAT_GUI
  1808.     if (!gui.in_use)
  1809. #endif
  1810.     get_stty();
  1811. #endif
  1812.  
  1813. /*
  1814.  * If the termcap has no entry for 'bs' and/or 'del' and the ioctl() also
  1815.  * didn't work, use the default CTRL-H
  1816.  * The default for t_kD is DEL, unless t_kb is DEL.
  1817.  * The vim_strsave'd strings are probably lost forever, well it's only two
  1818.  * bytes.  Don't do this when the GUI is active, it uses "t_kb" and "t_kD"
  1819.  * directly.
  1820.  */
  1821. #ifdef FEAT_GUI
  1822.     if (!gui.in_use)
  1823. #endif
  1824.     {
  1825.     bs_p = find_termcode((char_u *)"kb");
  1826.     del_p = find_termcode((char_u *)"kD");
  1827.     if (bs_p == NULL || *bs_p == NUL)
  1828.         add_termcode((char_u *)"kb", (bs_p = (char_u *)CTRL_H_STR), FALSE);
  1829.     if ((del_p == NULL || *del_p == NUL) &&
  1830.                         (bs_p == NULL || *bs_p != DEL))
  1831.         add_termcode((char_u *)"kD", (char_u *)DEL_STR, FALSE);
  1832.     }
  1833.  
  1834. #if defined(UNIX) || defined(VMS)
  1835.     term_is_xterm = vim_is_xterm(term);
  1836. #endif
  1837.  
  1838. #ifdef FEAT_MOUSE
  1839. # if defined(UNIX) || defined(VMS)
  1840. #  ifdef FEAT_MOUSE_TTY
  1841.     /*
  1842.      * For Unix, set the 'ttymouse' option to the type of mouse to be used.
  1843.      * The termcode for the mouse is added as a side effect in option.c.
  1844.      */
  1845.     {
  1846.     char_u    *p;
  1847.  
  1848.     p = (char_u *)"";
  1849. #  ifdef FEAT_MOUSE_XTERM
  1850. #   ifdef FEAT_CLIPBOARD
  1851. #    ifdef FEAT_GUI
  1852.     if (!gui.in_use)
  1853. #    endif
  1854.         clip_init(FALSE);
  1855. #   endif
  1856.     if (term_is_xterm)
  1857.     {
  1858.         if (use_xterm_mouse())
  1859.         p = NULL;    /* keep existing value, might be "xterm2" */
  1860.         else
  1861.         p = (char_u *)"xterm";
  1862.     }
  1863. #  endif
  1864.     if (p != NULL)
  1865.         set_option_value((char_u *)"ttym", 0L, p, 0);
  1866.     if (p == NULL
  1867. #   ifdef FEAT_GUI
  1868.         || gui.in_use
  1869. #   endif
  1870.         )
  1871.         check_mouse_termcode();    /* set mouse termcode anyway */
  1872.     }
  1873. #  endif
  1874. # else
  1875.     set_mouse_termcode(KS_MOUSE, (char_u *)"\233M");
  1876. # endif
  1877. #endif    /* FEAT_MOUSE */
  1878.  
  1879. #ifdef FEAT_SNIFF
  1880.     {
  1881.     char_u    name[2];
  1882.  
  1883.     name[0] = (int)KS_EXTRA;
  1884.     name[1] = (int)KE_SNIFF;
  1885.     add_termcode(name, (char_u *)"\233sniff", FALSE);
  1886.     }
  1887. #endif
  1888.  
  1889. #ifdef USE_TERM_CONSOLE
  1890.     /* DEFAULT_TERM indicates that it is the machine console. */
  1891.     if (STRCMP(term, DEFAULT_TERM))
  1892.     term_console = FALSE;
  1893.     else
  1894.     {
  1895.     term_console = TRUE;
  1896. # ifdef AMIGA
  1897.     win_resize_on();    /* enable window resizing reports */
  1898. # endif
  1899.     }
  1900. #endif
  1901.  
  1902. #if defined(UNIX) || defined(VMS)
  1903.     /*
  1904.      * 'ttyfast' is default on for xterm, iris-ansi and a few others.
  1905.      */
  1906.     if (vim_is_fastterm(term))
  1907.     p_tf = TRUE;
  1908. #endif
  1909. #ifdef USE_TERM_CONSOLE
  1910.     /*
  1911.      * 'ttyfast' is default on consoles
  1912.      */
  1913.     if (term_console)
  1914.     p_tf = TRUE;
  1915. #endif
  1916.  
  1917.     ttest(TRUE);    /* make sure we have a valid set of terminal codes */
  1918.  
  1919.     full_screen = TRUE;        /* we can use termcap codes from now on */
  1920.     set_term_defaults();    /* use current values as defaults */
  1921. #ifdef FEAT_TERMRESPONSE
  1922.     crv_status = CRV_GET;    /* Get terminal version later */
  1923. #endif
  1924.  
  1925.     /*
  1926.      * Initialize the terminal with the appropriate termcap codes.
  1927.      * Set the mouse and window title if possible.
  1928.      * Don't do this when starting, need to parse the .vimrc first, because it
  1929.      * may redefine t_TI etc.
  1930.      */
  1931.     if (starting != NO_SCREEN)
  1932.     {
  1933.     starttermcap();        /* may change terminal mode */
  1934. #ifdef FEAT_MOUSE
  1935.     setmouse();        /* may start using the mouse */
  1936. #endif
  1937. #ifdef FEAT_TITLE
  1938.     maketitle();        /* may display window title */
  1939. #endif
  1940.     }
  1941.  
  1942.     /* display initial screen after ttest() checking. jw. */
  1943.     if (width <= 0 || height <= 0)
  1944.     {
  1945.     /* termcap failed to report size */
  1946.     /* set defaults, in case ui_get_shellsize() also fails */
  1947.     width = 80;
  1948. #if defined(MSDOS) || defined(WIN3264)
  1949.     height = 25;        /* console is often 25 lines */
  1950. #else
  1951.     height = 24;        /* most terminals are 24 lines */
  1952. #endif
  1953.     }
  1954.     set_shellsize(width, height, FALSE);    /* may change Rows */
  1955.     if (starting != NO_SCREEN)
  1956.     {
  1957.     if (scroll_region)
  1958.         scroll_region_reset();        /* In case Rows changed */
  1959.     check_map_keycodes();    /* check mappings for terminal codes used */
  1960.  
  1961. #ifdef FEAT_AUTOCMD
  1962.     {
  1963.         buf_T    *old_curbuf;
  1964.  
  1965.         /*
  1966.          * Execute the TermChanged autocommands for each buffer that is
  1967.          * loaded.
  1968.          */
  1969.         old_curbuf = curbuf;
  1970.         for (curbuf = firstbuf; curbuf != NULL; curbuf = curbuf->b_next)
  1971.         {
  1972.         if (curbuf->b_ml.ml_mfp != NULL)
  1973.             apply_autocmds(EVENT_TERMCHANGED, NULL, NULL, FALSE,
  1974.                                       curbuf);
  1975.         }
  1976.         if (buf_valid(old_curbuf))
  1977.         curbuf = old_curbuf;
  1978.     }
  1979. #endif
  1980.     }
  1981.  
  1982. #ifdef FEAT_TERMRESPONSE
  1983.     may_req_termresponse();
  1984. #endif
  1985.  
  1986.     return OK;
  1987. }
  1988.  
  1989. #if defined(FEAT_MOUSE) || defined(PROTO)
  1990.  
  1991. # ifdef FEAT_MOUSE_TTY
  1992. #  define HMT_NORMAL    1
  1993. #  define HMT_NETTERM    2
  1994. #  define HMT_DEC    4
  1995. #  define HMT_JSBTERM    8
  1996. #  define HMT_PTERM    16
  1997. static int has_mouse_termcode = 0;
  1998. # endif
  1999.  
  2000. # if (!defined(UNIX) || defined(FEAT_MOUSE_XTERM) || defined(FEAT_MOUSE_NET) \
  2001.     || defined(FEAT_MOUSE_DEC)) || defined(FEAT_MOUSE_JSB) \
  2002.     || defined(FEAT_MOUSE_PTERM) || defined(PROTO)
  2003.     void
  2004. set_mouse_termcode(n, s)
  2005.     int        n;    /* KS_MOUSE, KS_NETTERM_MOUSE or KS_DEC_MOUSE */
  2006.     char_u    *s;
  2007. {
  2008.     char_u    name[2];
  2009.  
  2010.     name[0] = n;
  2011.     name[1] = KE_FILLER;
  2012.     add_termcode(name, s, FALSE);
  2013. #  ifdef FEAT_MOUSE_TTY
  2014. #   ifdef FEAT_MOUSE_JSB
  2015.     if (n == KS_JSBTERM_MOUSE)
  2016.     has_mouse_termcode |= HMT_JSBTERM;
  2017.     else
  2018. #   endif
  2019. #   ifdef FEAT_MOUSE_NET
  2020.     if (n == KS_NETTERM_MOUSE)
  2021.     has_mouse_termcode |= HMT_NETTERM;
  2022.     else
  2023. #   endif
  2024. #   ifdef FEAT_MOUSE_DEC
  2025.     if (n == KS_DEC_MOUSE)
  2026.     has_mouse_termcode |= HMT_DEC;
  2027.     else
  2028. #   endif
  2029. #   ifdef FEAT_MOUSE_PTERM
  2030.     if (n == KS_PTERM_MOUSE)
  2031.     has_mouse_termcode |= HMT_PTERM;
  2032.     else
  2033. #   endif
  2034.     has_mouse_termcode |= HMT_NORMAL;
  2035. #  endif
  2036. }
  2037. # endif
  2038.  
  2039. # if ((defined(UNIX) || defined(VMS) || defined(OS2)) \
  2040.     && (defined(FEAT_MOUSE_XTERM) || defined(FEAT_MOUSE_DEC) \
  2041.         || defined(FEAT_MOUSE_GPM) || defined(FEAT_MOUSE_PTERM))) \
  2042.         || defined(PROTO)
  2043.     void
  2044. del_mouse_termcode(n)
  2045.     int        n;    /* KS_MOUSE, KS_NETTERM_MOUSE or KS_DEC_MOUSE */
  2046. {
  2047.     char_u    name[2];
  2048.  
  2049.     name[0] = n;
  2050.     name[1] = KE_FILLER;
  2051.     del_termcode(name);
  2052. #  ifdef FEAT_MOUSE_TTY
  2053. #   ifdef FEAT_MOUSE_JSB
  2054.     if (n == KS_JSBTERM_MOUSE)
  2055.     has_mouse_termcode &= ~HMT_JSBTERM;
  2056.     else
  2057. #   endif
  2058. #   ifdef FEAT_MOUSE_NET
  2059.     if (n == KS_NETTERM_MOUSE)
  2060.     has_mouse_termcode &= ~HMT_NETTERM;
  2061.     else
  2062. #   endif
  2063. #   ifdef FEAT_MOUSE_DEC
  2064.     if (n == KS_DEC_MOUSE)
  2065.     has_mouse_termcode &= ~HMT_DEC;
  2066.     else
  2067. #   endif
  2068. #   ifdef FEAT_MOUSE_PTERM
  2069.     if (n == KS_PTERM_MOUSE)
  2070.     has_mouse_termcode &= ~HMT_PTERM;
  2071.     else
  2072. #   endif
  2073.     has_mouse_termcode &= ~HMT_NORMAL;
  2074. #  endif
  2075. }
  2076. # endif
  2077. #endif
  2078.  
  2079. #ifdef HAVE_TGETENT
  2080. /*
  2081.  * Call tgetent()
  2082.  * Return error message if it fails, NULL if it's OK.
  2083.  */
  2084.     static char_u *
  2085. tgetent_error(tbuf, term)
  2086.     char_u  *tbuf;
  2087.     char_u  *term;
  2088. {
  2089.     int        i;
  2090.  
  2091.     i = TGETENT(tbuf, term);
  2092.     if (i < 1)
  2093.     {
  2094.     /* On FreeBSD tputs() gets a SEGV after a tgetent() which fails.  Call
  2095.      * tgetent() with the always existing "dumb" entry to avoid a crash or
  2096.      * hang. */
  2097.     (void)TGETENT(tbuf, "dumb");
  2098.  
  2099.     if (i == -1)
  2100.         return (char_u *)_("Cannot open termcap file");
  2101.     if (i == 0)
  2102. #ifdef TERMINFO
  2103.         return (char_u *)_("Terminal entry not found in terminfo");
  2104. #else
  2105.     return (char_u *)_("Terminal entry not found in termcap");
  2106. #endif
  2107.     }
  2108.     return NULL;
  2109. }
  2110.  
  2111. /*
  2112.  * Some versions of tgetstr() have been reported to return -1 instead of NULL.
  2113.  * Fix that here.
  2114.  */
  2115.     static char_u *
  2116. vim_tgetstr(s, pp)
  2117.     char    *s;
  2118.     char_u    **pp;
  2119. {
  2120.     char    *p;
  2121.  
  2122.     p = tgetstr(s, (char **)pp);
  2123.     if (p == (char *)-1)
  2124.     p = NULL;
  2125.     return (char_u *)p;
  2126. }
  2127. #endif /* HAVE_TGETENT */
  2128.  
  2129. #if defined(HAVE_TGETENT) && (defined(UNIX) || defined(__EMX__) || defined(VMS) || defined(MACOS_X))
  2130. /*
  2131.  * Get Columns and Rows from the termcap. Used after a window signal if the
  2132.  * ioctl() fails. It doesn't make sense to call tgetent each time if the "co"
  2133.  * and "li" entries never change. But on some systems this works.
  2134.  * Errors while getting the entries are ignored.
  2135.  */
  2136.     void
  2137. getlinecol(cp, rp)
  2138.     long    *cp;    /* pointer to columns */
  2139.     long    *rp;    /* pointer to rows */
  2140. {
  2141.     char_u    tbuf[TBUFSZ];
  2142.  
  2143.     if (T_NAME != NULL && *T_NAME != NUL && tgetent_error(tbuf, T_NAME) == NULL)
  2144.     {
  2145.     if (*cp == 0)
  2146.         *cp = tgetnum("co");
  2147.     if (*rp == 0)
  2148.         *rp = tgetnum("li");
  2149.     }
  2150. }
  2151. #endif /* defined(HAVE_TGETENT) && defined(UNIX) */
  2152.  
  2153. /*
  2154.  * Get a string entry from the termcap and add it to the list of termcodes.
  2155.  * Used for <t_xx> special keys.
  2156.  * Give an error message for failure when not sourcing.
  2157.  * If force given, replace an existing entry.
  2158.  * Return FAIL if the entry was not found, OK if the entry was added.
  2159.  */
  2160.     int
  2161. add_termcap_entry(name, force)
  2162.     char_u  *name;
  2163.     int        force;
  2164. {
  2165.     char_u  *term;
  2166.     int        key;
  2167.     struct builtin_term *termp;
  2168. #ifdef HAVE_TGETENT
  2169.     char_u  *string;
  2170.     int        i;
  2171.     int        builtin_first;
  2172.     char_u  tbuf[TBUFSZ];
  2173.     char_u  tstrbuf[TBUFSZ];
  2174.     char_u  *tp = tstrbuf;
  2175.     char_u  *error_msg = NULL;
  2176. #endif
  2177.  
  2178. /*
  2179.  * If the GUI is running or will start in a moment, we only support the keys
  2180.  * that the GUI can produce.
  2181.  */
  2182. #ifdef FEAT_GUI
  2183.     if (gui.in_use || gui.starting)
  2184.     return gui_mch_haskey(name);
  2185. #endif
  2186.  
  2187.     if (!force && find_termcode(name) != NULL)        /* it's already there */
  2188.     return OK;
  2189.  
  2190.     term = T_NAME;
  2191.     if (term == NULL || *term == NUL)        /* 'term' not defined yet */
  2192.     return FAIL;
  2193.  
  2194.     if (term_is_builtin(term))            /* name starts with "builtin_" */
  2195.     {
  2196.     term += 8;
  2197. #ifdef HAVE_TGETENT
  2198.     builtin_first = TRUE;
  2199. #endif
  2200.     }
  2201. #ifdef HAVE_TGETENT
  2202.     else
  2203.     builtin_first = p_tbi;
  2204. #endif
  2205.  
  2206. #ifdef HAVE_TGETENT
  2207. /*
  2208.  * We can get the entry from the builtin termcap and from the external one.
  2209.  * If 'ttybuiltin' is on or the terminal name starts with "builtin_", try
  2210.  * builtin termcap first.
  2211.  * If 'ttybuiltin' is off, try external termcap first.
  2212.  */
  2213.     for (i = 0; i < 2; ++i)
  2214.     {
  2215.     if (!builtin_first == i)
  2216. #endif
  2217.     /*
  2218.      * Search in builtin termcap
  2219.      */
  2220.     {
  2221.         termp = find_builtin_term(term);
  2222.         if (termp->bt_string != NULL)    /* found it */
  2223.         {
  2224.         key = TERMCAP2KEY(name[0], name[1]);
  2225.         while (termp->bt_entry != (int)KS_NAME)
  2226.         {
  2227.             if ((int)termp->bt_entry == key)
  2228.             {
  2229.             add_termcode(name, (char_u *)termp->bt_string,
  2230.                               term_is_8bit(term));
  2231.             return OK;
  2232.             }
  2233.             ++termp;
  2234.         }
  2235.         }
  2236.     }
  2237. #ifdef HAVE_TGETENT
  2238.     else
  2239.     /*
  2240.      * Search in external termcap
  2241.      */
  2242.     {
  2243.         error_msg = tgetent_error(tbuf, term);
  2244.         if (error_msg == NULL)
  2245.         {
  2246.         string = TGETSTR((char *)name, &tp);
  2247.         if (string != NULL && *string != NUL)
  2248.         {
  2249.             add_termcode(name, string, FALSE);
  2250.             return OK;
  2251.         }
  2252.         }
  2253.     }
  2254.     }
  2255. #endif
  2256.  
  2257.     if (sourcing_name == NULL)
  2258.     {
  2259. #ifdef HAVE_TGETENT
  2260.     if (error_msg != NULL)
  2261.         EMSG(error_msg);
  2262.     else
  2263. #endif
  2264.         EMSG2(_("E436: No \"%s\" entry in termcap"), name);
  2265.     }
  2266.     return FAIL;
  2267. }
  2268.  
  2269.     static int
  2270. term_is_builtin(name)
  2271.     char_u  *name;
  2272. {
  2273.     return (STRNCMP(name, "builtin_", (size_t)8) == 0);
  2274. }
  2275.  
  2276. /*
  2277.  * Return TRUE if terminal "name" uses CSI instead of <Esc>[.
  2278.  * Assume that the terminal is using 8-bit controls when the name contains
  2279.  * "8bit", like in "xterm-8bit".
  2280.  */
  2281.     int
  2282. term_is_8bit(name)
  2283.     char_u  *name;
  2284. {
  2285.     return (detected_8bit || strstr((char *)name, "8bit") != NULL);
  2286. }
  2287.  
  2288. /*
  2289.  * Translate terminal control chars from 7-bit to 8-bit:
  2290.  * <Esc>[ -> CSI
  2291.  * <Esc>] -> <M-C-]>
  2292.  * <Esc>O -> <M-C-O>
  2293.  */
  2294.     static int
  2295. term_7to8bit(p)
  2296.     char_u  *p;
  2297. {
  2298.     if (*p == ESC)
  2299.     {
  2300.     if (p[1] == '[')
  2301.         return CSI;
  2302.     if (p[1] == ']')
  2303.         return 0x9d;
  2304.     if (p[1] == 'O')
  2305.         return 0x8f;
  2306.     }
  2307.     return 0;
  2308. }
  2309.  
  2310. #ifdef FEAT_GUI
  2311.     int
  2312. term_is_gui(name)
  2313.     char_u  *name;
  2314. {
  2315.     return (STRCMP(name, "builtin_gui") == 0 || STRCMP(name, "gui") == 0);
  2316. }
  2317. #endif
  2318.  
  2319. #if !defined(HAVE_TGETENT) || defined(AMIGA) || defined(PROTO)
  2320.  
  2321.     char_u *
  2322. tltoa(i)
  2323.     unsigned long i;
  2324. {
  2325.     static char_u buf[16];
  2326.     char_u    *p;
  2327.  
  2328.     p = buf + 15;
  2329.     *p = '\0';
  2330.     do
  2331.     {
  2332.     --p;
  2333.     *p = (char_u) (i % 10 + '0');
  2334.     i /= 10;
  2335.     }
  2336.     while (i > 0 && p > buf);
  2337.     return p;
  2338. }
  2339. #endif
  2340.  
  2341. #ifndef HAVE_TGETENT
  2342.  
  2343. /*
  2344.  * minimal tgoto() implementation.
  2345.  * no padding and we only parse for %i %d and %+char
  2346.  */
  2347. char *tgoto __ARGS((char *, int, int));
  2348.  
  2349.     char *
  2350. tgoto(cm, x, y)
  2351.     char *cm;
  2352.     int x, y;
  2353. {
  2354.     static char buf[30];
  2355.     char *p, *s, *e;
  2356.  
  2357.     if (!cm)
  2358.     return "OOPS";
  2359.     e = buf + 29;
  2360.     for (s = buf; s < e && *cm; cm++)
  2361.     {
  2362.     if (*cm != '%')
  2363.     {
  2364.         *s++ = *cm;
  2365.         continue;
  2366.     }
  2367.     switch (*++cm)
  2368.     {
  2369.     case 'd':
  2370.         p = (char *)tltoa((unsigned long)y);
  2371.         y = x;
  2372.         while (*p)
  2373.         *s++ = *p++;
  2374.         break;
  2375.     case 'i':
  2376.         x++;
  2377.         y++;
  2378.         break;
  2379.     case '+':
  2380.         *s++ = (char)(*++cm + y);
  2381.         y = x;
  2382.         break;
  2383.     case '%':
  2384.         *s++ = *cm;
  2385.         break;
  2386.     default:
  2387.         return "OOPS";
  2388.     }
  2389.     }
  2390.     *s = '\0';
  2391.     return buf;
  2392. }
  2393.  
  2394. #endif /* HAVE_TGETENT */
  2395.  
  2396. /*
  2397.  * Set the terminal name and initialize the terminal options.
  2398.  * If "name" is NULL or empty, get the terminal name from the environment.
  2399.  * If that fails, use the default terminal name.
  2400.  */
  2401.     void
  2402. termcapinit(name)
  2403.     char_u *name;
  2404. {
  2405.     char_u    *term;
  2406.  
  2407.     if (name != NULL && *name == NUL)
  2408.     name = NULL;        /* empty name is equal to no name */
  2409.     term = name;
  2410.  
  2411. #ifdef __BEOS__
  2412.     /*
  2413.      * TERM environment variable is normally set to 'ansi' on the Bebox;
  2414.      * Since the BeBox doesn't quite support full ANSI yet, we use our
  2415.      * own custom 'ansi-beos' termcap instead, unless the -T option has
  2416.      * been given on the command line.
  2417.      */
  2418.     if (term == NULL
  2419.          && strcmp((char *)mch_getenv((char_u *)"TERM"), "ansi") == 0)
  2420.     term = DEFAULT_TERM;
  2421. #endif
  2422. #ifndef MSWIN
  2423.     if (term == NULL)
  2424.     term = mch_getenv((char_u *)"TERM");
  2425. #endif
  2426.     if (term == NULL || *term == NUL)
  2427.     term = DEFAULT_TERM;
  2428.     set_string_option_direct((char_u *)"term", -1, term, OPT_FREE);
  2429.  
  2430.     /* Set the default terminal name. */
  2431.     set_string_default("term", term);
  2432.     set_string_default("ttytype", term);
  2433.  
  2434.     /*
  2435.      * Avoid using "term" here, because the next mch_getenv() may overwrite it.
  2436.      */
  2437.     set_termname(T_NAME != NULL ? T_NAME : term);
  2438. }
  2439.  
  2440. /*
  2441.  * the number of calls to ui_write is reduced by using the buffer "out_buf"
  2442.  */
  2443. #ifdef DOS16
  2444. # define OUT_SIZE    255        /* only have 640K total... */
  2445. #else
  2446. # ifdef FEAT_GUI_W16
  2447. #  define OUT_SIZE    1023        /* Save precious 1K near data */
  2448. # else
  2449. #  define OUT_SIZE    2047
  2450. # endif
  2451. #endif
  2452.         /* Add one to allow mch_write() in os_win32.c to append a NUL */
  2453. static char_u        out_buf[OUT_SIZE + 1];
  2454. static int        out_pos = 0;    /* number of chars in out_buf */
  2455.  
  2456. /*
  2457.  * out_flush(): flush the output buffer
  2458.  */
  2459.     void
  2460. out_flush()
  2461. {
  2462.     int        len;
  2463.  
  2464.     if (out_pos != 0)
  2465.     {
  2466.     /* set out_pos to 0 before ui_write, to avoid recursiveness */
  2467.     len = out_pos;
  2468.     out_pos = 0;
  2469.     ui_write(out_buf, len);
  2470.     }
  2471. }
  2472.  
  2473. #if defined(FEAT_MBYTE) || defined(PROTO)
  2474. /*
  2475.  * Sometimes a byte out of a multi-byte character is written with out_char().
  2476.  * To avoid flushing half of the character, call this function first.
  2477.  */
  2478.     void
  2479. out_flush_check()
  2480. {
  2481.     if (enc_dbcs != 0 && out_pos >= OUT_SIZE - MB_MAXBYTES)
  2482.     out_flush();
  2483. }
  2484. #endif
  2485.  
  2486. #ifdef FEAT_GUI
  2487. /*
  2488.  * out_trash(): Throw away the contents of the output buffer
  2489.  */
  2490.     void
  2491. out_trash()
  2492. {
  2493.     out_pos = 0;
  2494. }
  2495. #endif
  2496.  
  2497. /*
  2498.  * out_char(c): put a byte into the output buffer.
  2499.  *        Flush it if it becomes full.
  2500.  * This should not be used for outputting text on the screen (use functions
  2501.  * like msg_puts() and screen_putchar() for that).
  2502.  */
  2503.     void
  2504. out_char(c)
  2505.     unsigned    c;
  2506. {
  2507. #if defined(UNIX) || defined(VMS) || defined(AMIGA)
  2508.     if (c == '\n')    /* turn LF into CR-LF (CRMOD doesn't seem to do this) */
  2509.     out_char('\r');
  2510. #endif
  2511.  
  2512.     out_buf[out_pos++] = c;
  2513.  
  2514.     /* For testing we flush each time. */
  2515.     if (out_pos >= OUT_SIZE || p_wd)
  2516.     out_flush();
  2517. }
  2518.  
  2519. static void out_char_nf __ARGS((unsigned));
  2520.  
  2521. /*
  2522.  * out_char_nf(c): like out_char(), but don't flush when p_wd is set
  2523.  */
  2524.     static void
  2525. out_char_nf(c)
  2526.     unsigned    c;
  2527. {
  2528. #if defined(UNIX) || defined(VMS) || defined(AMIGA)
  2529.     if (c == '\n')    /* turn LF into CR-LF (CRMOD doesn't seem to do this) */
  2530.     out_char_nf('\r');
  2531. #endif
  2532.  
  2533.     out_buf[out_pos++] = c;
  2534.  
  2535.     if (out_pos >= OUT_SIZE)
  2536.     out_flush();
  2537. }
  2538.  
  2539. /*
  2540.  * A never-padding out_str.
  2541.  * use this whenever you don't want to run the string through tputs.
  2542.  * tputs above is harmless, but tputs from the termcap library
  2543.  * is likely to strip off leading digits, that it mistakes for padding
  2544.  * information, and "%i", "%d", etc.
  2545.  * This should only be used for writing terminal codes, not for outputting
  2546.  * normal text (use functions like msg_puts() and screen_putchar() for that).
  2547.  */
  2548.     void
  2549. out_str_nf(s)
  2550.     char_u *s;
  2551. {
  2552.     if (out_pos > OUT_SIZE - 20)  /* avoid terminal strings being split up */
  2553.     out_flush();
  2554.     while (*s)
  2555.     out_char_nf(*s++);
  2556.  
  2557.     /* For testing we write one string at a time. */
  2558.     if (p_wd)
  2559.     out_flush();
  2560. }
  2561.  
  2562. /*
  2563.  * out_str(s): Put a character string a byte at a time into the output buffer.
  2564.  * If HAVE_TGETENT is defined use the termcap parser. (jw)
  2565.  * This should only be used for writing terminal codes, not for outputting
  2566.  * normal text (use functions like msg_puts() and screen_putchar() for that).
  2567.  */
  2568.     void
  2569. out_str(s)
  2570.     char_u     *s;
  2571. {
  2572.     if (s != NULL && *s)
  2573.     {
  2574. #ifdef FEAT_GUI
  2575.     /* Don't use tputs() when GUI is used, ncurses crashes. */
  2576.     if (gui.in_use)
  2577.     {
  2578.         out_str_nf(s);
  2579.         return;
  2580.     }
  2581. #endif
  2582.     /* avoid terminal strings being split up */
  2583.     if (out_pos > OUT_SIZE - 20)
  2584.         out_flush();
  2585. #ifdef HAVE_TGETENT
  2586.     tputs((char *)s, 1, TPUTSFUNCAST out_char_nf);
  2587. #else
  2588.     while (*s)
  2589.         out_char_nf(*s++);
  2590. #endif
  2591.  
  2592.     /* For testing we write one string at a time. */
  2593.     if (p_wd)
  2594.         out_flush();
  2595.     }
  2596. }
  2597.  
  2598. /*
  2599.  * cursor positioning using termcap parser. (jw)
  2600.  */
  2601.     void
  2602. term_windgoto(row, col)
  2603.     int        row;
  2604.     int        col;
  2605. {
  2606.     OUT_STR(tgoto((char *)T_CM, col, row));
  2607. }
  2608.  
  2609.     void
  2610. term_cursor_right(i)
  2611.     int        i;
  2612. {
  2613.     OUT_STR(tgoto((char *)T_CRI, 0, i));
  2614. }
  2615.  
  2616.     void
  2617. term_append_lines(line_count)
  2618.     int        line_count;
  2619. {
  2620.     OUT_STR(tgoto((char *)T_CAL, 0, line_count));
  2621. }
  2622.  
  2623.     void
  2624. term_delete_lines(line_count)
  2625.     int        line_count;
  2626. {
  2627.     OUT_STR(tgoto((char *)T_CDL, 0, line_count));
  2628. }
  2629.  
  2630. #if defined(HAVE_TGETENT) || defined(PROTO)
  2631.     void
  2632. term_set_winpos(x, y)
  2633.     int        x;
  2634.     int        y;
  2635. {
  2636.     /* Can't handle a negative value here */
  2637.     if (x < 0)
  2638.     x = 0;
  2639.     if (y < 0)
  2640.     y = 0;
  2641.     OUT_STR(tgoto((char *)T_CWP, y, x));
  2642. }
  2643.  
  2644.     void
  2645. term_set_winsize(width, height)
  2646.     int        width;
  2647.     int        height;
  2648. {
  2649.     OUT_STR(tgoto((char *)T_CWS, height, width));
  2650. }
  2651. #endif
  2652.  
  2653.     void
  2654. term_fg_color(n)
  2655.     int        n;
  2656. {
  2657.     /* Use "AF" termcap entry if present, "Sf" entry otherwise */
  2658.     if (*T_CAF)
  2659.     term_color(T_CAF, n);
  2660.     else if (*T_CSF)
  2661.     term_color(T_CSF, n);
  2662. }
  2663.  
  2664.     void
  2665. term_bg_color(n)
  2666.     int        n;
  2667. {
  2668.     /* Use "AB" termcap entry if present, "Sb" entry otherwise */
  2669.     if (*T_CAB)
  2670.     term_color(T_CAB, n);
  2671.     else if (*T_CSB)
  2672.     term_color(T_CSB, n);
  2673. }
  2674.  
  2675.     static void
  2676. term_color(s, n)
  2677.     char_u    *s;
  2678.     int        n;
  2679. {
  2680.     char    buf[20];
  2681.     int i = 2;    /* index in s[] just after <Esc>[ or CSI */
  2682.  
  2683.     /* Special handling of 16 colors, because termcap can't handle it */
  2684.     /* Also accept "\e[3%dm" for TERMINFO, it is sometimes used */
  2685.     /* Also accept CSI instead of <Esc>[ */
  2686.     if (n >= 8 && t_colors >= 16
  2687.           && ((s[0] == ESC && s[1] == '[') || (s[0] == CSI && (i = 1) == 1))
  2688.           && s[i] != NUL
  2689.           && (STRCMP(s + i + 1, "%p1%dm") == 0
  2690.           || STRCMP(s + i + 1, "%dm") == 0)
  2691.           && (s[i] == '3' || s[i] == '4'))
  2692.     {
  2693.     sprintf(buf,
  2694. #ifdef TERMINFO
  2695.         "%s%s%%p1%%dm",
  2696. #else
  2697.         "%s%s%%dm",
  2698. #endif
  2699.         i == 2 ? IF_EB("\033[", ESC_STR "[") : "\233",
  2700.         s[i] == '3' ? (n >= 16 ? "38;5;" : "9")
  2701.                 : (n >= 16 ? "48;5;" : "10"));
  2702.     OUT_STR(tgoto(buf, 0, n >= 16 ? n : n - 8));
  2703.     }
  2704.     else
  2705.     OUT_STR(tgoto((char *)s, 0, n));
  2706. }
  2707.  
  2708. #if (defined(FEAT_TITLE) && (defined(UNIX) || defined(OS2) || defined(VMS) || defined(MACOS_X))) || defined(PROTO)
  2709. /*
  2710.  * Generic function to set window title, using t_ts and t_fs.
  2711.  */
  2712.     void
  2713. term_settitle(title)
  2714.     char_u    *title;
  2715. {
  2716.     /* t_ts takes one argument: column in status line */
  2717.     OUT_STR(tgoto((char *)T_TS, 0, 0));    /* set title start */
  2718.     out_str_nf(title);
  2719.     out_str(T_FS);            /* set title end */
  2720.     out_flush();
  2721. }
  2722. #endif
  2723.  
  2724. /*
  2725.  * Make sure we have a valid set or terminal options.
  2726.  * Replace all entries that are NULL by empty_option
  2727.  */
  2728.     void
  2729. ttest(pairs)
  2730.     int    pairs;
  2731. {
  2732.     check_options();            /* make sure no options are NULL */
  2733.  
  2734.     /*
  2735.      * MUST have "cm": cursor motion.
  2736.      */
  2737.     if (*T_CM == NUL)
  2738.     EMSG(_("E437: terminal capability \"cm\" required"));
  2739.  
  2740.     /*
  2741.      * if "cs" defined, use a scroll region, it's faster.
  2742.      */
  2743.     if (*T_CS != NUL)
  2744.     scroll_region = TRUE;
  2745.     else
  2746.     scroll_region = FALSE;
  2747.  
  2748.     if (pairs)
  2749.     {
  2750.     /*
  2751.      * optional pairs
  2752.      */
  2753.     /* TP goes to normal mode for TI (invert) and TB (bold) */
  2754.     if (*T_ME == NUL)
  2755.         T_ME = T_MR = T_MD = T_MB = empty_option;
  2756.     if (*T_SO == NUL || *T_SE == NUL)
  2757.         T_SO = T_SE = empty_option;
  2758.     if (*T_US == NUL || *T_UE == NUL)
  2759.         T_US = T_UE = empty_option;
  2760.     if (*T_CZH == NUL || *T_CZR == NUL)
  2761.         T_CZH = T_CZR = empty_option;
  2762.  
  2763.     /* T_VE is needed even though T_VI is not defined */
  2764.     if (*T_VE == NUL)
  2765.         T_VI = empty_option;
  2766.  
  2767.     /* if 'mr' or 'me' is not defined use 'so' and 'se' */
  2768.     if (*T_ME == NUL)
  2769.     {
  2770.         T_ME = T_SE;
  2771.         T_MR = T_SO;
  2772.         T_MD = T_SO;
  2773.     }
  2774.  
  2775.     /* if 'so' or 'se' is not defined use 'mr' and 'me' */
  2776.     if (*T_SO == NUL)
  2777.     {
  2778.         T_SE = T_ME;
  2779.         if (*T_MR == NUL)
  2780.         T_SO = T_MD;
  2781.         else
  2782.         T_SO = T_MR;
  2783.     }
  2784.  
  2785.     /* if 'ZH' or 'ZR' is not defined use 'mr' and 'me' */
  2786.     if (*T_CZH == NUL)
  2787.     {
  2788.         T_CZR = T_ME;
  2789.         if (*T_MR == NUL)
  2790.         T_CZH = T_MD;
  2791.         else
  2792.         T_CZH = T_MR;
  2793.     }
  2794.  
  2795.     /* "Sb" and "Sf" come in pairs */
  2796.     if (*T_CSB == NUL || *T_CSF == NUL)
  2797.     {
  2798.         T_CSB = empty_option;
  2799.         T_CSF = empty_option;
  2800.     }
  2801.  
  2802.     /* "AB" and "AF" come in pairs */
  2803.     if (*T_CAB == NUL || *T_CAF == NUL)
  2804.     {
  2805.         T_CAB = empty_option;
  2806.         T_CAF = empty_option;
  2807.     }
  2808.  
  2809.     /* if 'Sb' and 'AB' are not defined, reset "Co" */
  2810.     if (*T_CSB == NUL && *T_CAB == NUL)
  2811.         T_CCO = empty_option;
  2812.  
  2813.     /* Set 'weirdinvert' according to value of 't_xs' */
  2814.     p_wiv = (*T_XS != NUL);
  2815.     }
  2816.     need_gather = TRUE;
  2817.  
  2818.     /* Set t_colors to the value of t_Co. */
  2819.     t_colors = atoi((char *)T_CCO);
  2820. }
  2821.  
  2822. #if defined(FEAT_GUI) || defined(PROTO)
  2823. /*
  2824.  * Represent the given long_u as individual bytes, with the most significant
  2825.  * byte first, and store them in dst.
  2826.  */
  2827.     void
  2828. add_long_to_buf(val, dst)
  2829.     long_u  val;
  2830.     char_u  *dst;
  2831. {
  2832.     int        i;
  2833.     int        shift;
  2834.  
  2835.     for (i = 1; i <= sizeof(long_u); i++)
  2836.     {
  2837.     shift = 8 * (sizeof(long_u) - i);
  2838.     dst[i - 1] = (char_u) ((val >> shift) & 0xff);
  2839.     }
  2840. }
  2841.  
  2842. /*
  2843.  * Interpret the next string of bytes in buf as a long integer, with the most
  2844.  * significant byte first.  Note that it is assumed that buf has been through
  2845.  * inchar(), so that NUL and K_SPECIAL will be represented as three bytes each.
  2846.  * Puts result in val, and returns the number of bytes read from buf
  2847.  * (between sizeof(long_u) and 2 * sizeof(long_u)), or -1 if not enough bytes
  2848.  * were present.
  2849.  */
  2850.     int
  2851. get_long_from_buf(buf, val)
  2852.     char_u  *buf;
  2853.     long_u  *val;
  2854. {
  2855.     int        len;
  2856.     char_u  bytes[sizeof(long_u)];
  2857.     int        i;
  2858.     int        shift;
  2859.  
  2860.     *val = 0;
  2861.     len = get_bytes_from_buf(buf, bytes, (int)sizeof(long_u));
  2862.     if (len != -1)
  2863.     {
  2864.     for (i = 0; i < sizeof(long_u); i++)
  2865.     {
  2866.         shift = 8 * (sizeof(long_u) - 1 - i);
  2867.         *val += (long_u)bytes[i] << shift;
  2868.     }
  2869.     }
  2870.     return len;
  2871. }
  2872. #endif
  2873.  
  2874. #if defined(FEAT_GUI) \
  2875.     || (defined(FEAT_MOUSE) && (!defined(UNIX) || defined(FEAT_MOUSE_XTERM)))
  2876. /*
  2877.  * Read the next num_bytes bytes from buf, and store them in bytes.  Assume
  2878.  * that buf has been through inchar().    Returns the actual number of bytes used
  2879.  * from buf (between num_bytes and num_bytes*2), or -1 if not enough bytes were
  2880.  * available.
  2881.  */
  2882.     static int
  2883. get_bytes_from_buf(buf, bytes, num_bytes)
  2884.     char_u  *buf;
  2885.     char_u  *bytes;
  2886.     int        num_bytes;
  2887. {
  2888.     int        len = 0;
  2889.     int        i;
  2890.     char_u  c;
  2891.  
  2892.     for (i = 0; i < num_bytes; i++)
  2893.     {
  2894.     if ((c = buf[len++]) == NUL)
  2895.         return -1;
  2896.     if (c == K_SPECIAL)
  2897.     {
  2898.         if (buf[len] == NUL || buf[len + 1] == NUL)        /* cannot happen? */
  2899.         return -1;
  2900.         if (buf[len++] == (int)KS_ZERO)
  2901.         c = NUL;
  2902.         ++len;    /* skip KE_FILLER */
  2903.         /* else it should be KS_SPECIAL, and c already equals K_SPECIAL */
  2904.     }
  2905.     bytes[i] = c;
  2906.     }
  2907.     return len;
  2908. }
  2909. #endif
  2910.  
  2911. /*
  2912.  * Check if the new shell size is valid, correct it if it's too small.
  2913.  */
  2914.     void
  2915. check_shellsize()
  2916. {
  2917.     if (Columns < MIN_COLUMNS)
  2918.     Columns = MIN_COLUMNS;
  2919.     if (Rows < min_rows())    /* need room for one window and command line */
  2920.     Rows = min_rows();
  2921. }
  2922.  
  2923.     void
  2924. win_new_shellsize()
  2925. {
  2926.     static int    old_Rows = 0;
  2927.     static int    old_Columns = 0;
  2928.  
  2929.     if (old_Rows != Rows || old_Columns != Columns)
  2930.     ui_new_shellsize();
  2931.     if (old_Rows != Rows)
  2932.     {
  2933.     old_Rows = Rows;
  2934.     shell_new_rows();    /* update window sizes */
  2935.     }
  2936.     if (old_Columns != Columns)
  2937.     {
  2938.     old_Columns = Columns;
  2939. #ifdef FEAT_VERTSPLIT
  2940.     shell_new_columns();    /* update window sizes */
  2941. #endif
  2942.     }
  2943. }
  2944.  
  2945. /*
  2946.  * Call this function when the Vim shell has been resized in any way.
  2947.  * Will obtain the current size and redraw (also when size didn't change).
  2948.  */
  2949.     void
  2950. shell_resized()
  2951. {
  2952.     set_shellsize(0, 0, FALSE);
  2953. }
  2954.  
  2955. /*
  2956.  * Check if the shell size changed.  Handle a resize.
  2957.  * When the size didn't change, nothing happens.
  2958.  */
  2959.     void
  2960. shell_resized_check()
  2961. {
  2962.     int        old_Rows = Rows;
  2963.     int        old_Columns = Columns;
  2964.  
  2965.     (void)ui_get_shellsize();
  2966.     check_shellsize();
  2967.     if (old_Rows != Rows || old_Columns != Columns)
  2968.     shell_resized();
  2969. }
  2970.  
  2971. /*
  2972.  * Set size of the Vim shell.
  2973.  * If 'mustset' is TRUE, we must set Rows and Columns, do not get the real
  2974.  * window size (this is used for the :win command).
  2975.  * If 'mustset' is FALSE, we may try to get the real window size and if
  2976.  * it fails use 'width' and 'height'.
  2977.  */
  2978.     void
  2979. set_shellsize(width, height, mustset)
  2980.     int        width, height;
  2981.     int        mustset;
  2982. {
  2983.     static int        busy = FALSE;
  2984.  
  2985.     /*
  2986.      * Avoid recursiveness, can happen when setting the window size causes
  2987.      * another window-changed signal.
  2988.      */
  2989.     if (busy)
  2990.     return;
  2991.  
  2992.     if (width < 0 || height < 0)    /* just checking... */
  2993.     return;
  2994.  
  2995.     if (State == HITRETURN || State == SETWSIZE) /* postpone the resizing */
  2996.     {
  2997.     State = SETWSIZE;
  2998.     return;
  2999.     }
  3000.  
  3001.     ++busy;
  3002.  
  3003. #ifdef AMIGA
  3004.     out_flush();        /* must do this before mch_get_shellsize() for
  3005.                    some obscure reason */
  3006. #endif
  3007.  
  3008.     if (mustset || (ui_get_shellsize() == FAIL && height != 0))
  3009.     {
  3010.     Rows = height;
  3011.     Columns = width;
  3012.     check_shellsize();
  3013.     ui_set_shellsize(mustset);
  3014.     }
  3015.     else
  3016.     check_shellsize();
  3017.     win_new_shellsize();    /* fit the windows in the new sized shell */
  3018.  
  3019.     if (State != ASKMORE && State != EXTERNCMD && State != CONFIRM)
  3020.     screenclear();
  3021.     else
  3022.     screen_start();        /* don't know where cursor is now */
  3023.  
  3024.     if (starting != NO_SCREEN)
  3025.     {
  3026. #ifdef FEAT_TITLE
  3027.     maketitle();
  3028. #endif
  3029.     changed_line_abv_curs();
  3030.     invalidate_botline();
  3031.  
  3032.     /*
  3033.      * We only redraw when it's needed:
  3034.      * - While at the more prompt or executing an external command, don't
  3035.      *   redraw, but position the cursor.
  3036.      * - While editing the command line, only redraw that.
  3037.      * - in Ex mode, don't redraw anything.
  3038.      * - Otherwise, redraw right now, and position the cursor.
  3039.      * Always need to call update_screen() or screenalloc(), to make
  3040.      * sure Rows/Columns and the size of ScreenLines[] is correct!
  3041.      */
  3042.     if (State == ASKMORE || State == EXTERNCMD || State == CONFIRM
  3043.                                  || exmode_active)
  3044.     {
  3045.         screenalloc(FALSE);
  3046.         repeat_message();
  3047.     }
  3048.     else if (State & CMDLINE)
  3049.     {
  3050.         update_screen(NOT_VALID);
  3051.         redrawcmdline();
  3052.     }
  3053.     else
  3054.     {
  3055.         update_topline();
  3056.         update_screen(NOT_VALID);
  3057.         if (redrawing())
  3058.         setcursor();
  3059.     }
  3060.     cursor_on();        /* redrawing may have switched it off */
  3061.     }
  3062.     out_flush();
  3063.     --busy;
  3064. }
  3065.  
  3066. /*
  3067.  * Set the terminal to TMODE_RAW (for Normal mode) or TMODE_COOK (for external
  3068.  * commands and Ex mode).
  3069.  */
  3070.     void
  3071. settmode(tmode)
  3072.     int     tmode;
  3073. {
  3074. #ifdef FEAT_GUI
  3075.     /* don't set the term where gvim was started to any mode */
  3076.     if (gui.in_use)
  3077.     return;
  3078. #endif
  3079.  
  3080.     if (full_screen)
  3081.     {
  3082.     /* In Ex mode, never set to RAW */
  3083.     if (exmode_active == EXMODE_NORMAL)
  3084.         tmode = TMODE_COOK;
  3085.  
  3086.     /*
  3087.      * When returning after calling a shell we want to really set the
  3088.      * terminal to raw mode, even though we think it already is, because
  3089.      * the shell program may have reset the terminal mode.
  3090.      * When we think the terminal is normal, don't try to set it to
  3091.      * normal again, because that causes problems (logout!) on some
  3092.      * machines.
  3093.      */
  3094.     if (tmode != TMODE_COOK || cur_tmode != TMODE_COOK)
  3095.     {
  3096. #ifdef FEAT_TERMRESPONSE
  3097.         /* May need to check for T_CRV response and termcodes, it doesn't
  3098.          * work in Cooked mode, an external program may get them. */
  3099.         if (tmode != TMODE_RAW && crv_status == CRV_SENT)
  3100.         (void)vpeekc_nomap();
  3101.         check_for_codes_from_term();
  3102. #endif
  3103. #ifdef FEAT_MOUSE_TTY
  3104.         if (tmode != TMODE_RAW)
  3105.         mch_setmouse(FALSE);        /* switch mouse off */
  3106. #endif
  3107.         out_flush();
  3108.         mch_settmode(tmode);    /* machine specific function */
  3109.         cur_tmode = tmode;
  3110. #ifdef FEAT_MOUSE
  3111.         if (tmode == TMODE_RAW)
  3112.         setmouse();            /* may switch mouse on */
  3113. #endif
  3114.         out_flush();
  3115.     }
  3116. #ifdef FEAT_TERMRESPONSE
  3117.     may_req_termresponse();
  3118. #endif
  3119.     }
  3120. }
  3121.  
  3122.     void
  3123. starttermcap()
  3124. {
  3125.     screen_stop_highlight();
  3126.     if (full_screen && !termcap_active)
  3127.     {
  3128.     out_str(T_TI);            /* start termcap mode */
  3129.     out_str(T_KS);            /* start "keypad transmit" mode */
  3130.     out_flush();
  3131.     termcap_active = TRUE;
  3132.     screen_start();            /* don't know where cursor is now */
  3133. #ifdef FEAT_TERMRESPONSE
  3134.     may_req_termresponse();
  3135.     /* Immediately check for a response.  If t_Co changes, we don't want
  3136.      * to redraw with wrong colors first. */
  3137.     check_for_codes_from_term();
  3138. #endif
  3139.     }
  3140. }
  3141.  
  3142.     void
  3143. stoptermcap()
  3144. {
  3145.     screen_stop_highlight();
  3146.     reset_cterm_colors();
  3147.     if (termcap_active)
  3148.     {
  3149. #ifdef FEAT_TERMRESPONSE
  3150.     /* May need to check for T_CRV response. */
  3151.     if (crv_status == CRV_SENT)
  3152.         (void)vpeekc_nomap();
  3153.     /* Check for termcodes first, otherwise an external program may get
  3154.      * them. */
  3155.     check_for_codes_from_term();
  3156. #endif
  3157.     out_str(T_KE);            /* stop "keypad transmit" mode */
  3158.     out_flush();
  3159.     termcap_active = FALSE;
  3160.     cursor_on();            /* just in case it is still off */
  3161.     out_str(T_TE);            /* stop termcap mode */
  3162.     screen_start();            /* don't know where cursor is now */
  3163.     out_flush();
  3164.     }
  3165. }
  3166.  
  3167. #ifdef FEAT_TERMRESPONSE
  3168. /*
  3169.  * Request version string (for xterm) when needed.
  3170.  * Only do this after switching to raw mode, otherwise the result will be
  3171.  * echoed.
  3172.  * Only do this after termcap mode has been started, otherwise the codes for
  3173.  * the cursor keys may be wrong.
  3174.  * The result is caught in check_termcode().
  3175.  */
  3176.     static void
  3177. may_req_termresponse()
  3178. {
  3179.     if (crv_status == CRV_GET
  3180.         && cur_tmode == TMODE_RAW
  3181.         && termcap_active
  3182. #ifdef UNIX
  3183.         && isatty(1)
  3184. #endif
  3185.         && *T_CRV != NUL)
  3186.     {
  3187.     out_str(T_CRV);
  3188.     crv_status = CRV_SENT;
  3189.     /* check for the characters now, otherwise they might be eaten by
  3190.      * get_keystroke() */
  3191.     out_flush();
  3192.     (void)vpeekc_nomap();
  3193.     }
  3194. }
  3195. #endif
  3196.  
  3197. /*
  3198.  * Return TRUE when saving and restoring the screen.
  3199.  */
  3200.     int
  3201. swapping_screen()
  3202. {
  3203.     return (full_screen && *T_TI != NUL);
  3204. }
  3205.  
  3206. #ifdef FEAT_MOUSE
  3207. /*
  3208.  * setmouse() - switch mouse on/off depending on current mode and 'mouse'
  3209.  */
  3210.     void
  3211. setmouse()
  3212. {
  3213. # ifdef FEAT_MOUSE_TTY
  3214.     int        checkfor;
  3215. # endif
  3216.  
  3217. # ifdef FEAT_MOUSESHAPE
  3218.     update_mouseshape(-1);
  3219. # endif
  3220.  
  3221. # ifdef FEAT_MOUSE_TTY /* Should be outside proc, but may break MOUSESHAPE */
  3222. #  ifdef FEAT_GUI
  3223.     /* In the GUI the mouse is always enabled. */
  3224.     if (gui.in_use)
  3225.     return;
  3226. #  endif
  3227.     /* be quick when mouse is off */
  3228.     if (*p_mouse == NUL || has_mouse_termcode == 0)
  3229.     return;
  3230.  
  3231.     /* don't switch mouse on when not in raw mode (Ex mode) */
  3232.     if (cur_tmode != TMODE_RAW)
  3233.     {
  3234.     mch_setmouse(FALSE);
  3235.     return;
  3236.     }
  3237.  
  3238. #  ifdef FEAT_VISUAL
  3239.     if (VIsual_active)
  3240.     checkfor = MOUSE_VISUAL;
  3241.     else
  3242. #  endif
  3243.     if (State == HITRETURN || State == ASKMORE || State == SETWSIZE)
  3244.     checkfor = MOUSE_RETURN;
  3245.     else if (State & INSERT)
  3246.     checkfor = MOUSE_INSERT;
  3247.     else if (State & CMDLINE)
  3248.     checkfor = MOUSE_COMMAND;
  3249.     else if (State == CONFIRM || State == EXTERNCMD)
  3250.     checkfor = ' '; /* don't use mouse for ":confirm" or ":!cmd" */
  3251.     else
  3252.     checkfor = MOUSE_NORMAL;    /* assume normal mode */
  3253.  
  3254.     if (mouse_has(checkfor))
  3255.     mch_setmouse(TRUE);
  3256.     else
  3257.     mch_setmouse(FALSE);
  3258. # endif
  3259. }
  3260.  
  3261. /*
  3262.  * Return TRUE if
  3263.  * - "c" is in 'mouse', or
  3264.  * - 'a' is in 'mouse' and "c" is in MOUSE_A, or
  3265.  * - the current buffer is a help file and 'h' is in 'mouse' and we are in a
  3266.  *   normal editing mode (not at hit-return message).
  3267.  */
  3268.     int
  3269. mouse_has(c)
  3270.     int        c;
  3271. {
  3272.     char_u    *p;
  3273.  
  3274.     for (p = p_mouse; *p; ++p)
  3275.     switch (*p)
  3276.     {
  3277.         case 'a': if (vim_strchr((char_u *)MOUSE_A, c) != NULL)
  3278.               return TRUE;
  3279.               break;
  3280.         case MOUSE_HELP: if (c != MOUSE_RETURN && curbuf->b_help)
  3281.                  return TRUE;
  3282.                  break;
  3283.         default: if (c == *p) return TRUE; break;
  3284.     }
  3285.     return FALSE;
  3286. }
  3287.  
  3288. /*
  3289.  * Return TRUE when 'mousemodel' is set to "popup" or "popup_setpos".
  3290.  */
  3291.     int
  3292. mouse_model_popup()
  3293. {
  3294.     return (p_mousem[0] == 'p');
  3295. }
  3296. #endif
  3297.  
  3298. /*
  3299.  * By outputting the 'cursor very visible' termcap code, for some windowed
  3300.  * terminals this makes the screen scrolled to the correct position.
  3301.  * Used when starting Vim or returning from a shell.
  3302.  */
  3303.     void
  3304. scroll_start()
  3305. {
  3306.     if (*T_VS != NUL)
  3307.     {
  3308.     out_str(T_VS);
  3309.     out_str(T_VE);
  3310.     screen_start();            /* don't know where cursor is now */
  3311.     }
  3312. }
  3313.  
  3314. static int cursor_is_off = FALSE;
  3315.  
  3316. /*
  3317.  * Enable the cursor.
  3318.  */
  3319.     void
  3320. cursor_on()
  3321. {
  3322.     if (cursor_is_off)
  3323.     {
  3324.     out_str(T_VE);
  3325.     cursor_is_off = FALSE;
  3326.     }
  3327. }
  3328.  
  3329. /*
  3330.  * Disable the cursor.
  3331.  */
  3332.     void
  3333. cursor_off()
  3334. {
  3335.     if (full_screen)
  3336.     {
  3337.     if (!cursor_is_off)
  3338.         out_str(T_VI);        /* disable cursor */
  3339.     cursor_is_off = TRUE;
  3340.     }
  3341. }
  3342.  
  3343. /*
  3344.  * Set scrolling region for window 'wp'.
  3345.  * The region starts 'off' lines from the start of the window.
  3346.  * Also set the vertical scroll region for a vertically split window.  Always
  3347.  * the full width of the window, excluding the vertical separator.
  3348.  */
  3349.     void
  3350. scroll_region_set(wp, off)
  3351.     win_T    *wp;
  3352.     int        off;
  3353. {
  3354.     OUT_STR(tgoto((char *)T_CS, W_WINROW(wp) + wp->w_height - 1,
  3355.                              W_WINROW(wp) + off));
  3356. #ifdef FEAT_VERTSPLIT
  3357.     if (*T_CSV != NUL && wp->w_width != Columns)
  3358.     OUT_STR(tgoto((char *)T_CSV, W_WINCOL(wp) + wp->w_width - 1,
  3359.                                    W_WINCOL(wp)));
  3360. #endif
  3361.     screen_start();            /* don't know where cursor is now */
  3362. }
  3363.  
  3364. /*
  3365.  * Reset scrolling region to the whole screen.
  3366.  */
  3367.     void
  3368. scroll_region_reset()
  3369. {
  3370.     OUT_STR(tgoto((char *)T_CS, (int)Rows - 1, 0));
  3371. #ifdef FEAT_VERTSPLIT
  3372.     if (*T_CSV != NUL)
  3373.     OUT_STR(tgoto((char *)T_CSV, (int)Columns - 1, 0));
  3374. #endif
  3375.     screen_start();            /* don't know where cursor is now */
  3376. }
  3377.  
  3378.  
  3379. /*
  3380.  * List of terminal codes that are currently recognized.
  3381.  */
  3382.  
  3383. struct termcode
  3384. {
  3385.     char_u  name[2];        /* termcap name of entry */
  3386.     char_u  *code;        /* terminal code (in allocated memory) */
  3387.     int        len;        /* STRLEN(code) */
  3388. } *termcodes = NULL;
  3389.  
  3390. static int  tc_max_len = 0; /* number of entries that termcodes[] can hold */
  3391. static int  tc_len = 0;        /* current number of entries in termcodes[] */
  3392.  
  3393.     void
  3394. clear_termcodes()
  3395. {
  3396.     while (tc_len > 0)
  3397.     vim_free(termcodes[--tc_len].code);
  3398.     vim_free(termcodes);
  3399.     termcodes = NULL;
  3400.     tc_max_len = 0;
  3401.  
  3402. #ifdef HAVE_TGETENT
  3403.     BC = (char *)empty_option;
  3404.     UP = (char *)empty_option;
  3405.     PC = NUL;            /* set pad character to NUL */
  3406.     ospeed = 0;
  3407. #endif
  3408.  
  3409.     need_gather = TRUE;        /* need to fill termleader[] */
  3410. }
  3411.  
  3412. /*
  3413.  * Add a new entry to the list of terminal codes.
  3414.  * The list is kept alphabetical for ":set termcap"
  3415.  */
  3416.     void
  3417. add_termcode(name, string, use_8bit)
  3418.     char_u    *name;
  3419.     char_u    *string;
  3420.     int        use_8bit;    /* replace 7-bit control by 8-bit one */
  3421. {
  3422.     struct termcode *new_tc;
  3423.     int            i, j;
  3424.     char_u        *s;
  3425.  
  3426.     if (string == NULL || *string == NUL)
  3427.     {
  3428.     del_termcode(name);
  3429.     return;
  3430.     }
  3431.  
  3432.     s = vim_strsave(string);
  3433.     if (s == NULL)
  3434.     return;
  3435.  
  3436.     /* Change leading <Esc>[ to CSI, change <Esc>O to <M-O>. */
  3437.     if (use_8bit && term_7to8bit(string) != 0)
  3438.     {
  3439.     mch_memmove(s, s + 1, STRLEN(s));
  3440.     s[0] = term_7to8bit(string);
  3441.     }
  3442.  
  3443.     need_gather = TRUE;        /* need to fill termleader[] */
  3444.  
  3445.     /*
  3446.      * need to make space for more entries
  3447.      */
  3448.     if (tc_len == tc_max_len)
  3449.     {
  3450.     tc_max_len += 20;
  3451.     new_tc = (struct termcode *)alloc(
  3452.                 (unsigned)(tc_max_len * sizeof(struct termcode)));
  3453.     if (new_tc == NULL)
  3454.     {
  3455.         tc_max_len -= 20;
  3456.         return;
  3457.     }
  3458.     for (i = 0; i < tc_len; ++i)
  3459.         new_tc[i] = termcodes[i];
  3460.     vim_free(termcodes);
  3461.     termcodes = new_tc;
  3462.     }
  3463.  
  3464.     /*
  3465.      * Look for existing entry with the same name, it is replaced.
  3466.      * Look for an existing entry that is alphabetical higher, the new entry
  3467.      * is inserted in front of it.
  3468.      */
  3469.     for (i = 0; i < tc_len; ++i)
  3470.     {
  3471.     if (termcodes[i].name[0] < name[0])
  3472.         continue;
  3473.     if (termcodes[i].name[0] == name[0])
  3474.     {
  3475.         if (termcodes[i].name[1] < name[1])
  3476.         continue;
  3477.         /*
  3478.          * Exact match: Replace old code.
  3479.          */
  3480.         if (termcodes[i].name[1] == name[1])
  3481.         {
  3482.         vim_free(termcodes[i].code);
  3483.         --tc_len;
  3484.         break;
  3485.         }
  3486.     }
  3487.     /*
  3488.      * Found alphabetical larger entry, move rest to insert new entry
  3489.      */
  3490.     for (j = tc_len; j > i; --j)
  3491.         termcodes[j] = termcodes[j - 1];
  3492.     break;
  3493.     }
  3494.  
  3495.     termcodes[i].name[0] = name[0];
  3496.     termcodes[i].name[1] = name[1];
  3497.     termcodes[i].code = s;
  3498.     termcodes[i].len = (int)STRLEN(s);
  3499.     ++tc_len;
  3500. }
  3501.  
  3502.     char_u  *
  3503. find_termcode(name)
  3504.     char_u  *name;
  3505. {
  3506.     int        i;
  3507.  
  3508.     for (i = 0; i < tc_len; ++i)
  3509.     if (termcodes[i].name[0] == name[0] && termcodes[i].name[1] == name[1])
  3510.         return termcodes[i].code;
  3511.     return NULL;
  3512. }
  3513.  
  3514. #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
  3515.     char_u *
  3516. get_termcode(i)
  3517.     int        i;
  3518. {
  3519.     if (i >= tc_len)
  3520.     return NULL;
  3521.     return &termcodes[i].name[0];
  3522. }
  3523. #endif
  3524.  
  3525.     void
  3526. del_termcode(name)
  3527.     char_u  *name;
  3528. {
  3529.     int        i;
  3530.  
  3531.     if (termcodes == NULL)    /* nothing there yet */
  3532.     return;
  3533.  
  3534.     need_gather = TRUE;        /* need to fill termleader[] */
  3535.  
  3536.     for (i = 0; i < tc_len; ++i)
  3537.     if (termcodes[i].name[0] == name[0] && termcodes[i].name[1] == name[1])
  3538.     {
  3539.         del_termcode_idx(i);
  3540.         return;
  3541.     }
  3542.     /* not found. Give error message? */
  3543. }
  3544.  
  3545.     static void
  3546. del_termcode_idx(idx)
  3547.     int        idx;
  3548. {
  3549.     int        i;
  3550.  
  3551.     vim_free(termcodes[idx].code);
  3552.     --tc_len;
  3553.     for (i = idx; i < tc_len; ++i)
  3554.     termcodes[i] = termcodes[i + 1];
  3555. }
  3556.  
  3557. #ifdef FEAT_TERMRESPONSE
  3558. /*
  3559.  * Called when detected that the terminal sends 8-bit codes.
  3560.  * Convert all 7-bit codes to their 8-bit equivalent.
  3561.  */
  3562.     static void
  3563. switch_to_8bit()
  3564. {
  3565.     int        i;
  3566.     int        c;
  3567.  
  3568.     /* Only need to do something when not already using 8-bit codes. */
  3569.     if (!term_is_8bit(T_NAME))
  3570.     {
  3571.     for (i = 0; i < tc_len; ++i)
  3572.     {
  3573.         c = term_7to8bit(termcodes[i].code);
  3574.         if (c != 0)
  3575.         {
  3576.         mch_memmove(termcodes[i].code + 1, termcodes[i].code + 2,
  3577.                            STRLEN(termcodes[i].code + 1));
  3578.         termcodes[i].code[0] = c;
  3579.         }
  3580.     }
  3581.     need_gather = TRUE;        /* need to fill termleader[] */
  3582.     }
  3583.     detected_8bit = TRUE;
  3584. }
  3585. #endif
  3586.  
  3587. #ifdef CHECK_DOUBLE_CLICK
  3588. static linenr_T orig_topline = 0;
  3589. # ifdef FEAT_DIFF
  3590. static int orig_topfill = 0;
  3591. # endif
  3592. #endif
  3593. #if (defined(FEAT_WINDOWS) && defined(CHECK_DOUBLE_CLICK)) || defined(PROTO)
  3594. /*
  3595.  * Checking for double clicks ourselves.
  3596.  * "orig_topline" is used to avoid detecting a double-click when the window
  3597.  * contents scrolled (e.g., when 'scrolloff' is non-zero).
  3598.  */
  3599. /*
  3600.  * Set orig_topline.  Used when jumping to another window, so that a double
  3601.  * click still works.
  3602.  */
  3603.     void
  3604. set_mouse_topline(wp)
  3605.     win_T    *wp;
  3606. {
  3607.     orig_topline = wp->w_topline;
  3608. # ifdef FEAT_DIFF
  3609.     orig_topfill = wp->w_topfill;
  3610. # endif
  3611. }
  3612. #endif
  3613.  
  3614. /*
  3615.  * Check if typebuf.tb_buf[] contains a terminal key code.
  3616.  * Check from typebuf.tb_buf[typebuf.tb_off] to typebuf.tb_buf[typebuf.tb_off
  3617.  * + max_offset].
  3618.  * Return 0 for no match, -1 for partial match, > 0 for full match.
  3619.  * With a match, the match is removed, the replacement code is inserted in
  3620.  * typebuf.tb_buf[] and the number of characters in typebuf.tb_buf[] is
  3621.  * returned.
  3622.  * When "buf" is not NULL, it is used instead of typebuf.tb_buf[]. "buflen" is
  3623.  * then the length of the string in buf[].
  3624.  */
  3625.     int
  3626. check_termcode(max_offset, buf, buflen)
  3627.     int        max_offset;
  3628.     char_u    *buf;
  3629.     int        buflen;
  3630. {
  3631.     char_u    *tp;
  3632.     char_u    *p;
  3633.     int        slen = 0;    /* init for GCC */
  3634.     int        len;
  3635.     int        offset;
  3636.     char_u    key_name[2];
  3637.     int        new_slen;
  3638.     int        extra;
  3639.     char_u    string[MAX_KEY_CODE_LEN + 1];
  3640.     int        i, j;
  3641.     int        idx = 0;
  3642. #ifdef FEAT_GUI
  3643.     long_u    val;
  3644. #endif
  3645. #ifdef FEAT_MOUSE
  3646. # if !defined(UNIX) || defined(FEAT_MOUSE_XTERM) || defined(FEAT_GUI)
  3647.     char_u    bytes[3];
  3648.     int        num_bytes;
  3649. # endif
  3650.     int        mouse_code = 0;        /* init for GCC */
  3651.     int        modifiers;
  3652.     int        is_click, is_drag;
  3653.     int        wheel_code = 0;
  3654.     int        current_button;
  3655.     static int    held_button = MOUSE_RELEASE;
  3656.     static int    orig_num_clicks = 1;
  3657.     static int    orig_mouse_code = 0x0;
  3658. # ifdef CHECK_DOUBLE_CLICK
  3659.     static int    orig_mouse_col = 0;
  3660.     static int    orig_mouse_row = 0;
  3661.     static struct timeval  orig_mouse_time = {0, 0};
  3662.                     /* time of previous mouse click */
  3663.     struct timeval  mouse_time;        /* time of current mouse click */
  3664.     long    timediff;        /* elapsed time in msec */
  3665. # endif
  3666. #endif
  3667.     int        cpo_koffset;
  3668. #ifdef FEAT_MOUSE_GPM
  3669.     extern int    gpm_flag; /* gpm library variable */
  3670. #endif
  3671.  
  3672.     cpo_koffset = (vim_strchr(p_cpo, CPO_KOFFSET) != NULL);
  3673.  
  3674.     /*
  3675.      * Speed up the checks for terminal codes by gathering all first bytes
  3676.      * used in termleader[].  Often this is just a single <Esc>.
  3677.      */
  3678.     if (need_gather)
  3679.     gather_termleader();
  3680.  
  3681.     /*
  3682.      * Check at several positions in typebuf.tb_buf[], to catch something like
  3683.      * "x<Up>" that can be mapped. Stop at max_offset, because characters
  3684.      * after that cannot be used for mapping, and with @r commands
  3685.      * typebuf.tb_buf[]
  3686.      * can become very long.
  3687.      * This is used often, KEEP IT FAST!
  3688.      */
  3689.     for (offset = 0; offset < max_offset; ++offset)
  3690.     {
  3691.     if (buf == NULL)
  3692.     {
  3693.         if (offset >= typebuf.tb_len)
  3694.         break;
  3695.         tp = typebuf.tb_buf + typebuf.tb_off + offset;
  3696.         len = typebuf.tb_len - offset;    /* length of the input */
  3697.     }
  3698.     else
  3699.     {
  3700.         if (offset >= buflen)
  3701.         break;
  3702.         tp = buf + offset;
  3703.         len = buflen - offset;
  3704.     }
  3705.  
  3706.     /*
  3707.      * Don't check characters after K_SPECIAL, those are already
  3708.      * translated terminal chars (avoid translating ~@^Hx).
  3709.      */
  3710.     if (*tp == K_SPECIAL)
  3711.     {
  3712.         offset += 2;    /* there are always 2 extra characters */
  3713.         continue;
  3714.     }
  3715.  
  3716.     /*
  3717.      * Skip this position if the character does not appear as the first
  3718.      * character in term_strings. This speeds up a lot, since most
  3719.      * termcodes start with the same character (ESC or CSI).
  3720.      */
  3721.     i = *tp;
  3722.     for (p = termleader; *p && *p != i; ++p)
  3723.         ;
  3724.     if (*p == NUL)
  3725.         continue;
  3726.  
  3727.     /*
  3728.      * Skip this position if p_ek is not set and tp[0] is an ESC and we
  3729.      * are in Insert mode.
  3730.      */
  3731.     if (*tp == ESC && !p_ek && (State & INSERT))
  3732.         continue;
  3733.  
  3734.     new_slen = 0;        /* Length of what will replace the termcode */
  3735.     key_name[0] = NUL;    /* no key name found yet */
  3736.  
  3737. #ifdef FEAT_GUI
  3738.     if (gui.in_use)
  3739.     {
  3740.         /*
  3741.          * GUI special key codes are all of the form [CSI xx].
  3742.          */
  3743.         if (*tp == CSI)        /* Special key from GUI */
  3744.         {
  3745.         if (len < 3)
  3746.             return -1;        /* Shouldn't happen */
  3747.         slen = 3;
  3748.         key_name[0] = tp[1];
  3749.         key_name[1] = tp[2];
  3750.         }
  3751.     }
  3752.     else
  3753. #endif /* FEAT_GUI */
  3754.     {
  3755.         for (idx = 0; idx < tc_len; ++idx)
  3756.         {
  3757.         /*
  3758.          * Ignore the entry if we are not at the start of
  3759.          * typebuf.tb_buf[]
  3760.          * and there are not enough characters to make a match.
  3761.          * But only when the 'K' flag is in 'cpoptions'.
  3762.          */
  3763.         slen = termcodes[idx].len;
  3764.         if (cpo_koffset && offset && len < slen)
  3765.             continue;
  3766.         if (STRNCMP(termcodes[idx].code, tp,
  3767.                      (size_t)(slen > len ? len : slen)) == 0)
  3768.         {
  3769.             if (len < slen)        /* got a partial sequence */
  3770.             return -1;        /* need to get more chars */
  3771.  
  3772.             /*
  3773.              * When found a keypad key, check if there is another key
  3774.              * that matches and use that one.  This makes <Home> to be
  3775.              * found instead of <kHome> when they produce the same
  3776.              * key code.
  3777.              */
  3778.             if (termcodes[idx].name[0] == 'K'
  3779.                        && isdigit(termcodes[idx].name[1]))
  3780.             {
  3781.             for (j = idx + 1; j < tc_len; ++j)
  3782.                 if (termcodes[j].len == slen &&
  3783.                     STRNCMP(termcodes[idx].code,
  3784.                         termcodes[j].code, slen) == 0)
  3785.                 {
  3786.                 idx = j;
  3787.                 break;
  3788.                 }
  3789.             }
  3790.  
  3791.             key_name[0] = termcodes[idx].name[0];
  3792.             key_name[1] = termcodes[idx].name[1];
  3793.  
  3794.             break;
  3795.         }
  3796.         }
  3797.     }
  3798.  
  3799. #ifdef FEAT_TERMRESPONSE
  3800.     if (key_name[0] == NUL)
  3801.     {
  3802.         /* Check for xterm version string: "<Esc>[>{x};{vers};{y}c".  Also
  3803.          * eat other possible responses to t_RV, rxvt returns
  3804.          * "<Esc>[?1;2c".  Also accept CSI instead of <Esc>[. */
  3805.         if (*T_CRV != NUL && ((tp[0] == ESC && tp[1] == '[' && len >= 3)
  3806.                            || (tp[0] == CSI && len >= 2)))
  3807.         {
  3808.         j = 0;
  3809.         extra = 0;
  3810.         for (i = 2 + (tp[0] != CSI);
  3811.             i < len && (isdigit(tp[i])
  3812.                 || tp[i] == ';' || tp[i] == '.'); ++i)
  3813.             if (tp[i] == ';' && ++j == 1)
  3814.             extra = atoi((char *)tp + i + 1);
  3815.         if (i == len)
  3816.             return -1;        /* not enough characters */
  3817.  
  3818.         /* eat it when at least one digit and ending in 'c' */
  3819.         if (i > 2 + (tp[0] != CSI) && tp[i] == 'c')
  3820.         {
  3821.             crv_status = CRV_GOT;
  3822.  
  3823.             /* If this code starts with CSI, you can bet that the
  3824.              * terminal uses 8-bit codes. */
  3825.             if (tp[0] == CSI)
  3826.             switch_to_8bit();
  3827.  
  3828.             /* rxvt sends its version number: "20703" is 2.7.3.
  3829.              * Ignore it for when the user has set 'term' to xterm,
  3830.              * even though it's an rxvt. */
  3831.             if (extra > 20000)
  3832.             extra = 0;
  3833.  
  3834.             if (tp[1 + (tp[0] != CSI)] == '>' && j == 2)
  3835.             {
  3836.             /* if xterm version >= 95 use mouse dragging */
  3837.             if (extra >= 95)
  3838.                 set_option_value((char_u *)"ttym", 0L,
  3839.                                (char_u *)"xterm2", 0);
  3840.             /* if xterm version >= 141 try to get termcap codes */
  3841.             if (extra >= 141)
  3842.             {
  3843.                 check_for_codes = TRUE;
  3844.                 need_gather = TRUE;
  3845.                 req_codes_from_term();
  3846.             }
  3847.             }
  3848. # ifdef FEAT_EVAL
  3849.             set_vim_var_string(VV_TERMRESPONSE, tp, i + 1);
  3850. # endif
  3851. # ifdef FEAT_AUTOCMD
  3852.             apply_autocmds(EVENT_TERMRESPONSE,
  3853.                            NULL, NULL, FALSE, curbuf);
  3854. # endif
  3855.             key_name[0] = (int)KS_EXTRA;
  3856.             key_name[1] = (int)KE_IGNORE;
  3857.             slen = i + 1;
  3858.         }
  3859.         }
  3860.  
  3861.         /* Check for '<Esc>P1+r<hex bytes><Esc>\'.  A "0" instead of the
  3862.          * "1" means an invalid request. */
  3863.         else if (check_for_codes
  3864.             && ((tp[0] == ESC && tp[1] == 'P' && len >= 2)
  3865.             || tp[0] == DCS))
  3866.         {
  3867.         j = 1 + (tp[0] != DCS);
  3868.         for (i = j; i < len; ++i)
  3869.             if ((tp[i] == ESC && tp[i + 1] == '\\' && i + 1 < len)
  3870.                 || tp[i] == STERM)
  3871.             {
  3872.             if (i - j >= 3 && tp[j + 1] == '+' && tp[j + 2] == 'r')
  3873.                 got_code_from_term(tp + j, i);
  3874.             key_name[0] = (int)KS_EXTRA;
  3875.             key_name[1] = (int)KE_IGNORE;
  3876.             slen = i + 1 + (tp[i] == ESC);
  3877.             break;
  3878.             }
  3879.  
  3880.         if (i == len)
  3881.             return -1;        /* not enough characters */
  3882.         }
  3883.     }
  3884. #endif
  3885.  
  3886.     if (key_name[0] == NUL)
  3887.         continue;        /* No match at this position, try next one */
  3888.  
  3889.     /* We only get here when we have a complete termcode match */
  3890.  
  3891. #ifdef FEAT_MOUSE
  3892.     /*
  3893.      * If it is a mouse click, get the coordinates.
  3894.      */
  3895.     if (key_name[0] == (int)KS_MOUSE
  3896. # ifdef FEAT_MOUSE_JSB
  3897.         || key_name[0] == (int)KS_JSBTERM_MOUSE
  3898. # endif
  3899. # ifdef FEAT_MOUSE_NET
  3900.         || key_name[0] == (int)KS_NETTERM_MOUSE
  3901. # endif
  3902. # ifdef FEAT_MOUSE_DEC
  3903.         || key_name[0] == (int)KS_DEC_MOUSE
  3904. # endif
  3905. # ifdef FEAT_MOUSE_PTERM
  3906.         || key_name[0] == (int)KS_PTERM_MOUSE
  3907. # endif
  3908.         )
  3909.     {
  3910.         is_click = is_drag = FALSE;
  3911.  
  3912. # if !defined(UNIX) || defined(FEAT_MOUSE_XTERM) || defined(FEAT_GUI)
  3913.         if (key_name[0] == (int)KS_MOUSE)
  3914.         {
  3915.         /*
  3916.          * For xterm and MSDOS we get "<t_mouse>scr", where
  3917.          *  s == encoded button state:
  3918.          *       0x20 = left button down
  3919.          *       0x21 = middle button down
  3920.          *       0x22 = right button down
  3921.          *       0x23 = any button release
  3922.          *       0x60 = button 4 down (scroll wheel down)
  3923.          *       0x61 = button 5 down (scroll wheel up)
  3924.          *    add 0x04 for SHIFT
  3925.          *    add 0x08 for ALT
  3926.          *    add 0x10 for CTRL
  3927.          *    add 0x20 for mouse drag (0x40 is drag with left button)
  3928.          *  c == column + ' ' + 1 == column + 33
  3929.          *  r == row + ' ' + 1 == row + 33
  3930.          *
  3931.          * The coordinates are passed on through global variables.
  3932.          * Ugly, but this avoids trouble with mouse clicks at an
  3933.          * unexpected moment and allows for mapping them.
  3934.          */
  3935.         for (;;)
  3936.         {
  3937.             num_bytes = get_bytes_from_buf(tp + slen, bytes, 3);
  3938.             if (num_bytes == -1)    /* not enough coordinates */
  3939.             return -1;
  3940.             mouse_code = bytes[0];
  3941.             mouse_col = bytes[1] - ' ' - 1;
  3942.             mouse_row = bytes[2] - ' ' - 1;
  3943.             slen += num_bytes;
  3944.  
  3945.             /* If the following bytes is also a mouse code and it has
  3946.              * the same code, dump this one and get the next.  This
  3947.              * makes dragging a whole lot faster. */
  3948. #ifdef FEAT_GUI
  3949.             if (gui.in_use)
  3950.             j = 3;
  3951.             else
  3952. #endif
  3953.             j = termcodes[idx].len;
  3954.             if (STRNCMP(tp, tp + slen, (size_t)j) == 0
  3955.                 && tp[slen + j] == mouse_code
  3956.                 && tp[slen + j + 1] != NUL
  3957.                 && tp[slen + j + 2] != NUL)
  3958.             slen += j;
  3959.             else
  3960.             break;
  3961.         }
  3962.  
  3963. #  if !defined(MSWIN) && !defined(MSDOS)
  3964.         /*
  3965.          * Handle mouse events.
  3966.          * Recognize the xterm mouse wheel, but not in the GUI, the
  3967.          * Linux console with GPM and the MS-DOS or Win32 console
  3968.          * (multi-clicks use >= 0x60).
  3969.          */
  3970.         if (mouse_code >= MOUSEWHEEL_LOW
  3971. #   ifdef FEAT_GUI
  3972.             && !gui.in_use
  3973. #   endif
  3974. #   ifdef FEAT_MOUSE_GPM
  3975.             && gpm_flag == 0
  3976. #   endif
  3977.             )
  3978.         {
  3979.             /* Keep the mouse_code before it's changed, so that we
  3980.              * remember that it was a mouse wheel click. */
  3981.             wheel_code = mouse_code;
  3982.         }
  3983. #   if defined(UNIX) && defined(FEAT_MOUSE_TTY)
  3984.         else if (use_xterm_mouse() > 1)
  3985.         {
  3986.             if (mouse_code & MOUSE_DRAG_XTERM)
  3987.             mouse_code |= MOUSE_DRAG;
  3988.         }
  3989. #   endif
  3990. #   ifdef FEAT_XCLIPBOARD
  3991.         else if (!(mouse_code & MOUSE_DRAG & ~MOUSE_CLICK_MASK))
  3992.         {
  3993.             if ((mouse_code & MOUSE_RELEASE) == MOUSE_RELEASE)
  3994.             stop_xterm_trace();
  3995.             else
  3996.             start_xterm_trace(mouse_code);
  3997.         }
  3998. #   endif
  3999. #  endif
  4000.         }
  4001. # endif /* !UNIX || FEAT_MOUSE_XTERM */
  4002. # ifdef FEAT_MOUSE_NET
  4003.         if (key_name[0] == (int)KS_NETTERM_MOUSE)
  4004.         {
  4005.         int mc, mr;
  4006.  
  4007.         /* expect a rather limited sequence like: balancing {
  4008.          * \033}6,45\r
  4009.          * '6' is the row, 45 is the column
  4010.          */
  4011.         p = tp + slen;
  4012.         mr = getdigits(&p);
  4013.         if (*p++ != ',')
  4014.             return -1;
  4015.         mc = getdigits(&p);
  4016.         if (*p++ != '\r')
  4017.             return -1;
  4018.  
  4019.         mouse_col = mc - 1;
  4020.         mouse_row = mr - 1;
  4021.         mouse_code = MOUSE_LEFT;
  4022.         slen += (int)(p - (tp + slen));
  4023.         }
  4024. # endif    /* FEAT_MOUSE_NET */
  4025. # ifdef FEAT_MOUSE_JSB
  4026.         if (key_name[0] == (int)KS_JSBTERM_MOUSE)
  4027.         {
  4028.         int mult, val, iter, button, status;
  4029.  
  4030.         /* JSBTERM Input Model
  4031.          * \033[0~zw uniq escape sequence
  4032.          * (L-x)  Left button pressed - not pressed x not reporting
  4033.          * (M-x)  Middle button pressed - not pressed x not reporting
  4034.          * (R-x)  Right button pressed - not pressed x not reporting
  4035.          * (SDmdu)  Single , Double click, m mouse move d button down
  4036.          *                           u button up
  4037.          *  ###   X cursor position padded to 3 digits
  4038.          *  ###   Y cursor position padded to 3 digits
  4039.          * (s-x)  SHIFT key pressed - not pressed x not reporting
  4040.          * (c-x)  CTRL key pressed - not pressed x not reporting
  4041.          * \033\\ terminateing sequence
  4042.          */
  4043.  
  4044.         p = tp + slen;
  4045.         button = mouse_code = 0;
  4046.         switch (*p++)
  4047.         {
  4048.             case 'L': button = 1; break;
  4049.             case '-': break;
  4050.             case 'x': break; /* ignore sequence */
  4051.             default:  return -1; /* Unknown Result */
  4052.         }
  4053.         switch (*p++)
  4054.         {
  4055.             case 'M': button |= 2; break;
  4056.             case '-': break;
  4057.             case 'x': break; /* ignore sequence */
  4058.             default:  return -1; /* Unknown Result */
  4059.         }
  4060.         switch (*p++)
  4061.         {
  4062.             case 'R': button |= 4; break;
  4063.             case '-': break;
  4064.             case 'x': break; /* ignore sequence */
  4065.             default:  return -1; /* Unknown Result */
  4066.         }
  4067.         status = *p++;
  4068.         for (val = 0, mult = 100, iter = 0; iter < 3; iter++,
  4069.                                   mult /= 10, p++)
  4070.             if (*p >= '0' && *p <= '9')
  4071.             val += (*p - '0') * mult;
  4072.             else
  4073.             return -1;
  4074.         mouse_col = val;
  4075.         for (val = 0, mult = 100, iter = 0; iter < 3; iter++,
  4076.                                   mult /= 10, p++)
  4077.             if (*p >= '0' && *p <= '9')
  4078.             val += (*p - '0') * mult;
  4079.             else
  4080.             return -1;
  4081.         mouse_row = val;
  4082.         switch (*p++)
  4083.         {
  4084.             case 's': button |= 8; break;  /* SHIFT key Pressed */
  4085.             case '-': break;  /* Not Pressed */
  4086.             case 'x': break;  /* Not Reporting */
  4087.             default:  return -1; /* Unknown Result */
  4088.         }
  4089.         switch (*p++)
  4090.         {
  4091.             case 'c': button |= 16; break;  /* CTRL key Pressed */
  4092.             case '-': break;  /* Not Pressed */
  4093.             case 'x': break;  /* Not Reporting */
  4094.             default:  return -1; /* Unknown Result */
  4095.         }
  4096.         if (*p++ != '\033')
  4097.             return -1;
  4098.         if (*p++ != '\\')
  4099.             return -1;
  4100.         switch (status)
  4101.         {
  4102.             case 'D': /* Double Click */
  4103.             case 'S': /* Single Click */
  4104.             if (button & 1) mouse_code |= MOUSE_LEFT;
  4105.             if (button & 2) mouse_code |= MOUSE_MIDDLE;
  4106.             if (button & 4) mouse_code |= MOUSE_RIGHT;
  4107.             if (button & 8) mouse_code |= MOUSE_SHIFT;
  4108.             if (button & 16) mouse_code |= MOUSE_CTRL;
  4109.             break;
  4110.             case 'm': /* Mouse move */
  4111.             if (button & 1) mouse_code |= MOUSE_LEFT;
  4112.             if (button & 2) mouse_code |= MOUSE_MIDDLE;
  4113.             if (button & 4) mouse_code |= MOUSE_RIGHT;
  4114.             if (button & 8) mouse_code |= MOUSE_SHIFT;
  4115.             if (button & 16) mouse_code |= MOUSE_CTRL;
  4116.             if ((button & 7) != 0)
  4117.             {
  4118.                 held_button = mouse_code;
  4119.                 mouse_code |= MOUSE_DRAG;
  4120.             }
  4121.             is_drag = TRUE;
  4122.             showmode();
  4123.             break;
  4124.             case 'd': /* Button Down */
  4125.             if (button & 1) mouse_code |= MOUSE_LEFT;
  4126.             if (button & 2) mouse_code |= MOUSE_MIDDLE;
  4127.             if (button & 4) mouse_code |= MOUSE_RIGHT;
  4128.             if (button & 8) mouse_code |= MOUSE_SHIFT;
  4129.             if (button & 16) mouse_code |= MOUSE_CTRL;
  4130.             break;
  4131.             case 'u': /* Button Up */
  4132.             if (button & 1)
  4133.                 mouse_code |= MOUSE_LEFT | MOUSE_RELEASE;
  4134.             if (button & 2)
  4135.                 mouse_code |= MOUSE_MIDDLE | MOUSE_RELEASE;
  4136.             if (button & 4)
  4137.                 mouse_code |= MOUSE_RIGHT | MOUSE_RELEASE;
  4138.             if (button & 8)
  4139.                 mouse_code |= MOUSE_SHIFT;
  4140.             if (button & 16)
  4141.                 mouse_code |= MOUSE_CTRL;
  4142.             break;
  4143.             default: return -1; /* Unknown Result */
  4144.         }
  4145.  
  4146.         slen += (p - (tp + slen));
  4147.         }
  4148. # endif /* FEAT_MOUSE_JSB */
  4149. # ifdef FEAT_MOUSE_DEC
  4150.         if (key_name[0] == (int)KS_DEC_MOUSE)
  4151.         {
  4152.            /* The DEC Locator Input Model
  4153.         * Netterm delivers the code sequence:
  4154.         *  \033[2;4;24;80&w  (left button down)
  4155.         *  \033[3;0;24;80&w  (left button up)
  4156.         *  \033[6;1;24;80&w  (right button down)
  4157.         *  \033[7;0;24;80&w  (right button up)
  4158.         * CSI Pe ; Pb ; Pr ; Pc ; Pp & w
  4159.         * Pe is the event code
  4160.         * Pb is the button code
  4161.         * Pr is the row coordinate
  4162.         * Pc is the column coordinate
  4163.         * Pp is the third coordinate (page number)
  4164.         * Pe, the event code indicates what event caused this report
  4165.         *    The following event codes are defined:
  4166.         *    0 - request, the terminal received an explicit request
  4167.         *     for a locator report, but the locator is unavailable
  4168.         *    1 - request, the terminal received an explicit request
  4169.         *     for a locator report
  4170.         *    2 - left button down
  4171.         *    3 - left button up
  4172.         *    4 - middle button down
  4173.         *    5 - middle button up
  4174.         *    6 - right button down
  4175.         *    7 - right button up
  4176.         *    8 - fourth button down
  4177.         *    9 - fourth button up
  4178.         *    10 - locator outside filter rectangle
  4179.         * Pb, the button code, ASCII decimal 0-15 indicating which
  4180.         *   buttons are down if any. The state of the four buttons
  4181.         *   on the locator correspond to the low four bits of the
  4182.         *   decimal value,
  4183.         *   "1" means button depressed
  4184.         *   0 - no buttons down,
  4185.         *   1 - right,
  4186.         *   2 - middle,
  4187.         *   4 - left,
  4188.         *   8 - fourth
  4189.         * Pr is the row coordinate of the locator position in the page,
  4190.         *   encoded as an ASCII decimal value.
  4191.         *   If Pr is omitted, the locator position is undefined
  4192.         *   (outside the terminal window for example).
  4193.         * Pc is the column coordinate of the locator position in the
  4194.         *   page, encoded as an ASCII decimal value.
  4195.         *   If Pc is omitted, the locator position is undefined
  4196.         *   (outside the terminal window for example).
  4197.         * Pp is the page coordinate of the locator position
  4198.         *   encoded as an ASCII decimal value.
  4199.         *   The page coordinate may be omitted if the locator is on
  4200.         *   page one (the default).
  4201.         */
  4202.         int Pe, Pb, Pr, Pc /* , Pp */;
  4203.  
  4204.         p = tp + slen;
  4205.  
  4206.         /* get event status */
  4207.         Pe = getdigits(&p);
  4208.         if (*p++ != ';')
  4209.             return -1;
  4210.  
  4211.         /* get button status */
  4212.         Pb = getdigits(&p);
  4213.         if (*p++ != ';')
  4214.             return -1;
  4215.  
  4216.         /* get row status */
  4217.         Pr = getdigits(&p);
  4218.         if (*p++ != ';')
  4219.             return -1;
  4220.  
  4221.         /* get column status */
  4222.         Pc = getdigits(&p);
  4223.  
  4224.         /* the page parameter is optional */
  4225.         if (*p == ';')
  4226.         {
  4227.             p++;
  4228.             /* Pp = getdigits(&p); */
  4229.         }
  4230.         /* else
  4231.             Pp = 0; */
  4232.         if (*p++ != '&')
  4233.             return -1;
  4234.         if (*p++ != 'w')
  4235.             return -1;
  4236.  
  4237.         mouse_code = 0;
  4238.         switch (Pe)
  4239.         {
  4240.         case  0: return -1; /* position request while unavailable */
  4241.         case  1: /* a response to a locator position request includes
  4242.                 the status of all buttons */
  4243.              Pb &= 7;   /* mask off and ignore fourth button */
  4244.              if (Pb & 4)
  4245.                  mouse_code  = MOUSE_LEFT;
  4246.              if (Pb & 2)
  4247.                  mouse_code  = MOUSE_MIDDLE;
  4248.              if (Pb & 1)
  4249.                  mouse_code  = MOUSE_RIGHT;
  4250.              if (Pb)
  4251.              {
  4252.                  held_button = mouse_code;
  4253.                  mouse_code |= MOUSE_DRAG;
  4254.                  WantQueryMouse = 1;
  4255.              }
  4256.              is_drag = TRUE;
  4257.              showmode();
  4258.              break;
  4259.         case  2: mouse_code = MOUSE_LEFT;
  4260.              WantQueryMouse = 1;
  4261.              break;
  4262.         case  3: mouse_code = MOUSE_RELEASE | MOUSE_LEFT;
  4263.              break;
  4264.         case  4: mouse_code = MOUSE_MIDDLE;
  4265.              WantQueryMouse = 1;
  4266.              break;
  4267.         case  5: mouse_code = MOUSE_RELEASE | MOUSE_MIDDLE;
  4268.              break;
  4269.         case  6: mouse_code = MOUSE_RIGHT;
  4270.              WantQueryMouse = 1;
  4271.              break;
  4272.         case  7: mouse_code = MOUSE_RELEASE | MOUSE_RIGHT;
  4273.              break;
  4274.         case  8: return -1; /* fourth button down */
  4275.         case  9: return -1; /* fourth button up */
  4276.         case 10: return -1; /* mouse outside of filter rectangle */
  4277.         default: return -1; /* should never occur */
  4278.         }
  4279.  
  4280.         /* we ignore the Pp word */
  4281.         mouse_col = Pc - 1;
  4282.         mouse_row = Pr - 1;
  4283.  
  4284.         slen += (int)(p - (tp + slen));
  4285.         }
  4286. # endif /* FEAT_MOUSE_DEC */
  4287. # ifdef FEAT_MOUSE_PTERM
  4288.         if (key_name[0] == (int)KS_PTERM_MOUSE)
  4289.         {
  4290.         int button, num_clicks, action, mc, mr;
  4291.  
  4292.         p = tp + slen;
  4293.  
  4294.         action = getdigits(&p);
  4295.         if (*p++ != ';')
  4296.             return -1;
  4297.  
  4298.         mouse_row = getdigits(&p);
  4299.         if (*p++ != ';')
  4300.             return -1;
  4301.         mouse_col = getdigits(&p);
  4302.         if (*p++ != ';')
  4303.             return -1;
  4304.  
  4305.         button = getdigits(&p);
  4306.         mouse_code = 0;
  4307.  
  4308.         switch( button )
  4309.         {
  4310.             case 4: mouse_code = MOUSE_LEFT; break;
  4311.             case 1: mouse_code = MOUSE_RIGHT; break;
  4312.             case 2: mouse_code = MOUSE_MIDDLE; break;
  4313.             default: return -1;
  4314.         }
  4315.  
  4316.         switch( action )
  4317.         {
  4318.             case 31: /* Initial press */
  4319.             if (*p++ != ';')
  4320.                 return -1;
  4321.  
  4322.             num_clicks = getdigits(&p); /* Not used */
  4323.             break;
  4324.  
  4325.             case 32: /* Release */
  4326.             mouse_code |= MOUSE_RELEASE;
  4327.             break;
  4328.  
  4329.             case 33: /* Drag */
  4330.             held_button = mouse_code;
  4331.             mouse_code |= MOUSE_DRAG;
  4332.             break;
  4333.  
  4334.             default:
  4335.             return -1;
  4336.         }
  4337.  
  4338.         if (*p++ != 't')
  4339.             return -1;
  4340.  
  4341.         slen += (p - (tp + slen));
  4342.         }
  4343. # endif /* FEAT_MOUSE_PTERM */
  4344.  
  4345.         /* Interpret the mouse code */
  4346.         current_button = (mouse_code & MOUSE_CLICK_MASK);
  4347.         if (current_button == MOUSE_RELEASE)
  4348.         {
  4349.         /*
  4350.          * If we get a mouse drag or release event when
  4351.          * there is no mouse button held down (held_button ==
  4352.          * MOUSE_RELEASE), produce a K_IGNORE below.
  4353.          * (can happen when you hold down two buttons
  4354.          * and then let them go, or click in the menu bar, but not
  4355.          * on a menu, and drag into the text).
  4356.          */
  4357.         if ((mouse_code & MOUSE_DRAG) == MOUSE_DRAG)
  4358.             is_drag = TRUE;
  4359.         current_button = held_button;
  4360.         }
  4361.         else if (wheel_code == 0)
  4362.         {
  4363. # ifdef CHECK_DOUBLE_CLICK
  4364. #  ifdef FEAT_MOUSE_GPM
  4365. #   ifdef FEAT_GUI
  4366.         /*
  4367.          * Only for Unix, when GUI or gpm is not active, we handle
  4368.          * multi-clicks here.
  4369.          */
  4370.         if (gpm_flag == 0 && !gui.in_use)
  4371. #   else
  4372.         if (gpm_flag == 0)
  4373. #   endif
  4374. #  else
  4375. #   ifdef FEAT_GUI
  4376.         if (!gui.in_use)
  4377. #   endif
  4378. #  endif
  4379.         {
  4380.             /*
  4381.              * Compute the time elapsed since the previous mouse click.
  4382.              */
  4383.             gettimeofday(&mouse_time, NULL);
  4384.             timediff = (mouse_time.tv_usec
  4385.                         - orig_mouse_time.tv_usec) / 1000;
  4386.             if (timediff < 0)
  4387.             --orig_mouse_time.tv_sec;
  4388.             timediff += (mouse_time.tv_sec
  4389.                          - orig_mouse_time.tv_sec) * 1000;
  4390.             orig_mouse_time = mouse_time;
  4391.             if (mouse_code == orig_mouse_code
  4392.                 && timediff < p_mouset
  4393.                 && orig_num_clicks != 4
  4394.                 && orig_mouse_col == mouse_col
  4395.                 && orig_mouse_row == mouse_row
  4396. #ifdef FEAT_DIFF
  4397.                 && orig_topfill == curwin->w_topfill
  4398. #endif
  4399.                 && orig_topline == curwin->w_topline)
  4400.             ++orig_num_clicks;
  4401.             else
  4402.             orig_num_clicks = 1;
  4403.             orig_mouse_col = mouse_col;
  4404.             orig_mouse_row = mouse_row;
  4405.             orig_topline = curwin->w_topline;
  4406. #ifdef FEAT_DIFF
  4407.             orig_topfill = curwin->w_topfill;
  4408. #endif
  4409.         }
  4410. #  if defined(FEAT_GUI) || defined(FEAT_MOUSE_GPM)
  4411.         else
  4412.             orig_num_clicks = NUM_MOUSE_CLICKS(mouse_code);
  4413. #  endif
  4414. # else
  4415.         orig_num_clicks = NUM_MOUSE_CLICKS(mouse_code);
  4416. # endif
  4417.         is_click = TRUE;
  4418.         orig_mouse_code = mouse_code;
  4419.         }
  4420.         if (!is_drag)
  4421.         held_button = mouse_code & MOUSE_CLICK_MASK;
  4422.  
  4423.         /*
  4424.          * Translate the actual mouse event into a pseudo mouse event.
  4425.          * First work out what modifiers are to be used.
  4426.          */
  4427.         modifiers = 0x0;
  4428.         if (orig_mouse_code & MOUSE_SHIFT)
  4429.         modifiers |= MOD_MASK_SHIFT;
  4430.         if (orig_mouse_code & MOUSE_CTRL)
  4431.         modifiers |= MOD_MASK_CTRL;
  4432.         if (orig_mouse_code & MOUSE_ALT)
  4433.         modifiers |= MOD_MASK_ALT;
  4434.         if (orig_num_clicks == 2)
  4435.         modifiers |= MOD_MASK_2CLICK;
  4436.         else if (orig_num_clicks == 3)
  4437.         modifiers |= MOD_MASK_3CLICK;
  4438.         else if (orig_num_clicks == 4)
  4439.         modifiers |= MOD_MASK_4CLICK;
  4440.  
  4441.         /* Add the modifier codes to our string */
  4442.         if (modifiers != 0)
  4443.         {
  4444.         string[new_slen++] = K_SPECIAL;
  4445.         string[new_slen++] = (int)KS_MODIFIER;
  4446.         string[new_slen++] = modifiers;
  4447.         }
  4448.  
  4449.         /* Work out our pseudo mouse event */
  4450.         key_name[0] = (int)KS_EXTRA;
  4451.         if (wheel_code != 0)
  4452.         key_name[1] = (wheel_code & 1)
  4453.                     ? (int)KE_MOUSEUP : (int)KE_MOUSEDOWN;
  4454.         else
  4455.         key_name[1] = get_pseudo_mouse_code(current_button,
  4456.                                is_click, is_drag);
  4457.     }
  4458. #endif /* FEAT_MOUSE */
  4459.  
  4460. #ifdef FEAT_GUI
  4461.     /*
  4462.      * If using the GUI, then we get menu and scrollbar events.
  4463.      *
  4464.      * A menu event is encoded as K_SPECIAL, KS_MENU, KE_FILLER followed by
  4465.      * four bytes which are to be taken as a pointer to the vimmenu_T
  4466.      * structure.
  4467.      *
  4468.      * A scrollbar event is K_SPECIAL, KS_VER_SCROLLBAR, KE_FILLER followed
  4469.      * by one byte representing the scrollbar number, and then four bytes
  4470.      * representing a long_u which is the new value of the scrollbar.
  4471.      *
  4472.      * A horizontal scrollbar event is K_SPECIAL, KS_HOR_SCROLLBAR,
  4473.      * KE_FILLER followed by four bytes representing a long_u which is the
  4474.      * new value of the scrollbar.
  4475.      */
  4476.     else if (key_name[0] == (int)KS_MENU)
  4477.     {
  4478.         num_bytes = get_long_from_buf(tp + slen, &val);
  4479.         if (num_bytes == -1)
  4480.         return -1;
  4481.         current_menu = (vimmenu_T *)val;
  4482.         slen += num_bytes;
  4483.     }
  4484.     else if (key_name[0] == (int)KS_VER_SCROLLBAR)
  4485.     {
  4486.         /* Get the last scrollbar event in the queue of the same type */
  4487.         j = 0;
  4488.         for (i = 0; tp[j] == CSI && tp[j + 1] == KS_VER_SCROLLBAR
  4489.                              && tp[j + 2] != NUL; ++i)
  4490.         {
  4491.         j += 3;
  4492.         num_bytes = get_bytes_from_buf(tp + j, bytes, 1);
  4493.         if (num_bytes == -1)
  4494.             break;
  4495.         if (i == 0)
  4496.             current_scrollbar = (int)bytes[0];
  4497.         else if (current_scrollbar != (int)bytes[0])
  4498.             break;
  4499.         j += num_bytes;
  4500.         num_bytes = get_long_from_buf(tp + j, &val);
  4501.         if (num_bytes == -1)
  4502.             break;
  4503.         scrollbar_value = val;
  4504.         j += num_bytes;
  4505.         slen = j;
  4506.         }
  4507.         if (i == 0)        /* not enough characters to make one */
  4508.         return -1;
  4509.     }
  4510.     else if (key_name[0] == (int)KS_HOR_SCROLLBAR)
  4511.     {
  4512.         /* Get the last horiz. scrollbar event in the queue */
  4513.         j = 0;
  4514.         for (i = 0; tp[j] == CSI && tp[j + 1] == KS_HOR_SCROLLBAR
  4515.                              && tp[j + 2] != NUL; ++i)
  4516.         {
  4517.         j += 3;
  4518.         num_bytes = get_long_from_buf(tp + j, &val);
  4519.         if (num_bytes == -1)
  4520.             break;
  4521.         scrollbar_value = val;
  4522.         j += num_bytes;
  4523.         slen = j;
  4524.         }
  4525.         if (i == 0)        /* not enough characters to make one */
  4526.         return -1;
  4527.     }
  4528. #endif /* FEAT_GUI */
  4529.     /* Finally, add the special key code to our string */
  4530.     if (key_name[0] == KS_KEY)
  4531.         string[new_slen++] = key_name[1];    /* from ":set <M-b>=xx" */
  4532.     else
  4533.     {
  4534.         string[new_slen++] = K_SPECIAL;
  4535.         string[new_slen++] = key_name[0];
  4536.         string[new_slen++] = key_name[1];
  4537.     }
  4538.     string[new_slen] = NUL;
  4539.     extra = new_slen - slen;
  4540.     if (buf == NULL)
  4541.     {
  4542.         if (extra < 0)
  4543.         /* remove matched chars, taking care of noremap */
  4544.         del_typebuf(-extra, offset);
  4545.         else if (extra > 0)
  4546.         /* insert the extra space we need */
  4547.         ins_typebuf(string + slen, REMAP_YES, offset, FALSE, FALSE);
  4548.  
  4549.         /*
  4550.          * Careful: del_typebuf() and ins_typebuf() may have reallocated
  4551.          * typebuf.tb_buf[]!
  4552.          */
  4553.         mch_memmove(typebuf.tb_buf + typebuf.tb_off + offset, string,
  4554.                                 (size_t)new_slen);
  4555.     }
  4556.     else
  4557.     {
  4558.         if (extra < 0)
  4559.         /* remove matched characters */
  4560.         mch_memmove(buf + offset, buf + offset - extra,
  4561.                        (size_t)(buflen + offset + extra));
  4562.         else if (extra > 0)
  4563.         /* insert the extra space we need */
  4564.         mch_memmove(buf + offset + extra, buf + offset,
  4565.                            (size_t)(buflen - offset));
  4566.         mch_memmove(buf + offset, string, (size_t)new_slen);
  4567.     }
  4568.     return (len + extra + offset);
  4569.     }
  4570.  
  4571.     return 0;                /* no match found */
  4572. }
  4573.  
  4574. /*
  4575.  * Replace any terminal code strings in from[] with the equivalent internal
  4576.  * vim representation.    This is used for the "from" and "to" part of a
  4577.  * mapping, and the "to" part of a menu command.
  4578.  * Any strings like "<C-UP>" are also replaced, unless 'cpoptions' contains
  4579.  * '<'.
  4580.  * K_SPECIAL by itself is replaced by K_SPECIAL KS_SPECIAL KE_FILLER.
  4581.  *
  4582.  * The replacement is done in result[] and finally copied into allocated
  4583.  * memory. If this all works well *bufp is set to the allocated memory and a
  4584.  * pointer to it is returned. If something fails *bufp is set to NULL and from
  4585.  * is returned.
  4586.  *
  4587.  * CTRL-V characters are removed.  When "from_part" is TRUE, a trailing CTRL-V
  4588.  * is included, otherwise it is removed (for ":map xx ^V", maps xx to
  4589.  * nothing).  When 'cpoptions' does not contain 'B', a backslash can be used
  4590.  * instead of a CTRL-V.
  4591.  */
  4592.     char_u  *
  4593. replace_termcodes(from, bufp, from_part, do_lt)
  4594.     char_u    *from;
  4595.     char_u    **bufp;
  4596.     int        from_part;
  4597.     int        do_lt;        /* also translate <lt> */
  4598. {
  4599.     int        i;
  4600.     int        slen;
  4601.     int        key;
  4602.     int        dlen = 0;
  4603.     char_u    *src;
  4604.     int        do_backslash;    /* backslash is a special character */
  4605.     int        do_special;    /* recognize <> key codes */
  4606.     int        do_key_code;    /* recognize raw key codes */
  4607.     char_u    *result;    /* buffer for resulting string */
  4608.  
  4609.     do_backslash = (vim_strchr(p_cpo, CPO_BSLASH) == NULL);
  4610.     do_special = (vim_strchr(p_cpo, CPO_SPECI) == NULL);
  4611.     do_key_code = (vim_strchr(p_cpo, CPO_KEYCODE) == NULL);
  4612.  
  4613.     /*
  4614.      * Allocate space for the translation.  Worst case a single character is
  4615.      * replaced by 6 bytes (shifted special key), plus a NUL at the end.
  4616.      */
  4617.     result = alloc((unsigned)STRLEN(from) * 6 + 1);
  4618.     if (result == NULL)        /* out of memory */
  4619.     {
  4620.     *bufp = NULL;
  4621.     return from;
  4622.     }
  4623.  
  4624.     src = from;
  4625.  
  4626.     /*
  4627.      * Check for #n at start only: function key n
  4628.      */
  4629.     if (from_part && src[0] == '#' && isdigit(src[1]))        /* function key */
  4630.     {
  4631.     result[dlen++] = K_SPECIAL;
  4632.     result[dlen++] = 'k';
  4633.     if (src[1] == '0')
  4634.         result[dlen++] = ';';    /* #0 is F10 is "k;" */
  4635.     else
  4636.         result[dlen++] = src[1];    /* #3 is F3 is "k3" */
  4637.     src += 2;
  4638.     }
  4639.  
  4640.     /*
  4641.      * Copy each byte from *from to result[dlen]
  4642.      */
  4643.     while (*src != NUL)
  4644.     {
  4645.     /*
  4646.      * If 'cpoptions' does not contain '<', check for special key codes,
  4647.      * like "<C-S-MouseLeft>"
  4648.      */
  4649.     if (do_special && (do_lt || STRNCMP(src, "<lt>", 4) != 0))
  4650.     {
  4651. #ifdef FEAT_EVAL
  4652.         /*
  4653.          * Replace <SID> by K_SNR <script-nr> _.
  4654.          * (room: 5 * 6 = 30 bytes; needed: 3 + <nr> + 1 <= 14)
  4655.          */
  4656.         if (STRNICMP(src, "<SID>", 5) == 0)
  4657.         {
  4658.         if (current_SID <= 0)
  4659.             EMSG(_(e_usingsid));
  4660.         else
  4661.         {
  4662.             src += 5;
  4663.             result[dlen++] = K_SPECIAL;
  4664.             result[dlen++] = (int)KS_EXTRA;
  4665.             result[dlen++] = (int)KE_SNR;
  4666.             sprintf((char *)result + dlen, "%ld", (long)current_SID);
  4667.             dlen += (int)STRLEN(result + dlen);
  4668.             result[dlen++] = '_';
  4669.             continue;
  4670.         }
  4671.         }
  4672. #endif
  4673.  
  4674.         slen = trans_special(&src, result + dlen, TRUE);
  4675.         if (slen)
  4676.         {
  4677.         dlen += slen;
  4678.         continue;
  4679.         }
  4680.     }
  4681.  
  4682.     /*
  4683.      * If 'cpoptions' does not contain 'k', see if it's an actual key-code.
  4684.      * Note that this is also checked after replacing the <> form.
  4685.      * Single character codes are NOT replaced (e.g. ^H or DEL), because
  4686.      * it could be a character in the file.
  4687.      */
  4688.     if (do_key_code)
  4689.     {
  4690.         i = find_term_bykeys(src);
  4691.         if (i >= 0)
  4692.         {
  4693.         result[dlen++] = K_SPECIAL;
  4694.         result[dlen++] = termcodes[i].name[0];
  4695.         result[dlen++] = termcodes[i].name[1];
  4696.         src += termcodes[i].len;
  4697.         /* If terminal code matched, continue after it. */
  4698.         continue;
  4699.         }
  4700.     }
  4701.  
  4702. #ifdef FEAT_EVAL
  4703.     if (do_special)
  4704.     {
  4705.         char_u    *p, *s, len;
  4706.  
  4707.         /*
  4708.          * Replace <Leader> by the value of "mapleader".
  4709.          * Replace <LocalLeader> by the value of "maplocalleader".
  4710.          * If "mapleader" or "maplocalleader" isn't set use a backslash.
  4711.          */
  4712.         if (STRNICMP(src, "<Leader>", 8) == 0)
  4713.         {
  4714.         len = 8;
  4715.         p = get_var_value((char_u *)"mapleader");
  4716.         }
  4717.         else if (STRNICMP(src, "<LocalLeader>", 13) == 0)
  4718.         {
  4719.         len = 13;
  4720.         p = get_var_value((char_u *)"maplocalleader");
  4721.         }
  4722.         else
  4723.         {
  4724.         len = 0;
  4725.         p = NULL;
  4726.         }
  4727.         if (len != 0)
  4728.         {
  4729.         /* Allow up to 8 * 6 characters for "mapleader". */
  4730.         if (p == NULL || *p == NUL || STRLEN(p) > 8 * 6)
  4731.             s = (char_u *)"\\";
  4732.         else
  4733.             s = p;
  4734.         while (*s != NUL)
  4735.             result[dlen++] = *s++;
  4736.         src += len;
  4737.         continue;
  4738.         }
  4739.     }
  4740. #endif
  4741.  
  4742.     /*
  4743.      * Remove CTRL-V and ignore the next character.
  4744.      * For "from" side the CTRL-V at the end is included, for the "to"
  4745.      * part it is removed.
  4746.      * If 'cpoptions' does not contain 'B', also accept a backslash.
  4747.      */
  4748.     key = *src;
  4749.     if (key == Ctrl_V || (do_backslash && key == '\\'))
  4750.     {
  4751.         ++src;                /* skip CTRL-V or backslash */
  4752.         if (*src == NUL)
  4753.         {
  4754.         if (from_part)
  4755.             result[dlen++] = key;
  4756.         break;
  4757.         }
  4758.     }
  4759.  
  4760. #ifdef FEAT_MBYTE
  4761.     /* skip multibyte char correctly */
  4762.     for (i = (*mb_ptr2len_check)(src); i > 0; --i)
  4763. #endif
  4764.     {
  4765.         /*
  4766.          * If the character is K_SPECIAL, replace it with K_SPECIAL
  4767.          * KS_SPECIAL KE_FILLER.
  4768.          * If compiled with the GUI replace CSI with K_CSI.
  4769.          */
  4770.         if (*src == K_SPECIAL)
  4771.         {
  4772.         result[dlen++] = K_SPECIAL;
  4773.         result[dlen++] = KS_SPECIAL;
  4774.         result[dlen++] = KE_FILLER;
  4775.         }
  4776. # ifdef FEAT_GUI
  4777.         else if (*src == CSI)
  4778.         {
  4779.         result[dlen++] = K_SPECIAL;
  4780.         result[dlen++] = KS_EXTRA;
  4781.         result[dlen++] = (int)KE_CSI;
  4782.         }
  4783. # endif
  4784.         else
  4785.         result[dlen++] = *src;
  4786.         ++src;
  4787.     }
  4788.     }
  4789.     result[dlen] = NUL;
  4790.  
  4791.     /*
  4792.      * Copy the new string to allocated memory.
  4793.      * If this fails, just return from.
  4794.      */
  4795.     if ((*bufp = vim_strsave(result)) != NULL)
  4796.     from = *bufp;
  4797.     vim_free(result);
  4798.     return from;
  4799. }
  4800.  
  4801. /*
  4802.  * Find a termcode with keys 'src' (must be NUL terminated).
  4803.  * Return the index in termcodes[], or -1 if not found.
  4804.  */
  4805.     int
  4806. find_term_bykeys(src)
  4807.     char_u    *src;
  4808. {
  4809.     int        i;
  4810.     int        slen;
  4811.  
  4812.     for (i = 0; i < tc_len; ++i)
  4813.     {
  4814.     slen = termcodes[i].len;
  4815.     if (slen > 1 && STRNCMP(termcodes[i].code, src, (size_t)slen) == 0)
  4816.         return i;
  4817.     }
  4818.     return -1;
  4819. }
  4820.  
  4821. /*
  4822.  * Gather the first characters in the terminal key codes into a string.
  4823.  * Used to speed up check_termcode().
  4824.  */
  4825.     static void
  4826. gather_termleader()
  4827. {
  4828.     int        i;
  4829.     int        len = 0;
  4830.  
  4831. #ifdef FEAT_GUI
  4832.     if (gui.in_use)
  4833.     termleader[len++] = CSI;    /* the GUI codes are not in termcodes[] */
  4834. #endif
  4835. #ifdef FEAT_TERMRESPONSE
  4836.     if (check_for_codes)
  4837.     termleader[len++] = DCS;    /* the termcode response starts with DCS
  4838.                        in 8-bit mode */
  4839. #endif
  4840.     termleader[len] = NUL;
  4841.  
  4842.     for (i = 0; i < tc_len; ++i)
  4843.     if (vim_strchr(termleader, termcodes[i].code[0]) == NULL)
  4844.     {
  4845.         termleader[len++] = termcodes[i].code[0];
  4846.         termleader[len] = NUL;
  4847.     }
  4848.  
  4849.     need_gather = FALSE;
  4850. }
  4851.  
  4852. /*
  4853.  * Show all termcodes (for ":set termcap")
  4854.  * This code looks a lot like showoptions(), but is different.
  4855.  */
  4856.     void
  4857. show_termcodes()
  4858. {
  4859.     int        col;
  4860.     int        *items;
  4861.     int        item_count;
  4862.     int        run;
  4863.     int        row, rows;
  4864.     int        cols;
  4865.     int        i;
  4866.     int        len;
  4867.  
  4868. #define INC 27        /* try to make three columns */
  4869. #define GAP 2        /* spaces between columns */
  4870.  
  4871.     if (tc_len == 0)        /* no terminal codes (must be GUI) */
  4872.     return;
  4873.     items = (int *)alloc((unsigned)(sizeof(int) * tc_len));
  4874.     if (items == NULL)
  4875.     return;
  4876.  
  4877.     /* Highlight title */
  4878.     MSG_PUTS_TITLE(_("\n--- Terminal keys ---"));
  4879.  
  4880.     /*
  4881.      * do the loop two times:
  4882.      * 1. display the short items (non-strings and short strings)
  4883.      * 2. display the long items (strings)
  4884.      */
  4885.     for (run = 1; run <= 2 && !got_int; ++run)
  4886.     {
  4887.     /*
  4888.      * collect the items in items[]
  4889.      */
  4890.     item_count = 0;
  4891.     for (i = 0; i < tc_len; i++)
  4892.     {
  4893.         len = show_one_termcode(termcodes[i].name,
  4894.                             termcodes[i].code, FALSE);
  4895.         if ((len <= INC - GAP && run == 1) || (len > INC - GAP && run == 2))
  4896.         items[item_count++] = i;
  4897.     }
  4898.  
  4899.     /*
  4900.      * display the items
  4901.      */
  4902.     if (run == 1)
  4903.     {
  4904.         cols = (Columns + GAP) / INC;
  4905.         if (cols == 0)
  4906.         cols = 1;
  4907.         rows = (item_count + cols - 1) / cols;
  4908.     }
  4909.     else    /* run == 2 */
  4910.         rows = item_count;
  4911.     for (row = 0; row < rows && !got_int; ++row)
  4912.     {
  4913.         msg_putchar('\n');            /* go to next line */
  4914.         if (got_int)            /* 'q' typed in more */
  4915.         break;
  4916.         col = 0;
  4917.         for (i = row; i < item_count; i += rows)
  4918.         {
  4919.         msg_col = col;            /* make columns */
  4920.         show_one_termcode(termcodes[items[i]].name,
  4921.                           termcodes[items[i]].code, TRUE);
  4922.         col += INC;
  4923.         }
  4924.         out_flush();
  4925.         ui_breakcheck();
  4926.     }
  4927.     }
  4928.     vim_free(items);
  4929. }
  4930.  
  4931. /*
  4932.  * Show one termcode entry.
  4933.  * Output goes into IObuff[]
  4934.  */
  4935.     int
  4936. show_one_termcode(name, code, printit)
  4937.     char_u  *name;
  4938.     char_u  *code;
  4939.     int        printit;
  4940. {
  4941.     char_u    *p;
  4942.     int        len;
  4943.  
  4944.     if (name[0] > '~')
  4945.     {
  4946.     IObuff[0] = ' ';
  4947.     IObuff[1] = ' ';
  4948.     IObuff[2] = ' ';
  4949.     IObuff[3] = ' ';
  4950.     }
  4951.     else
  4952.     {
  4953.     IObuff[0] = 't';
  4954.     IObuff[1] = '_';
  4955.     IObuff[2] = name[0];
  4956.     IObuff[3] = name[1];
  4957.     }
  4958.     IObuff[4] = ' ';
  4959.  
  4960.     p = get_special_key_name(TERMCAP2KEY(name[0], name[1]), 0);
  4961.     if (p[1] != 't')
  4962.     STRCPY(IObuff + 5, p);
  4963.     else
  4964.     IObuff[5] = NUL;
  4965.     len = (int)STRLEN(IObuff);
  4966.     do
  4967.     IObuff[len++] = ' ';
  4968.     while (len < 17);
  4969.     IObuff[len] = NUL;
  4970.     if (code == NULL)
  4971.     len += 4;
  4972.     else
  4973.     len += vim_strsize(code);
  4974.  
  4975.     if (printit)
  4976.     {
  4977.     msg_puts(IObuff);
  4978.     if (code == NULL)
  4979.         msg_puts((char_u *)"NULL");
  4980.     else
  4981.         msg_outtrans(code);
  4982.     }
  4983.     return len;
  4984. }
  4985.  
  4986. #if defined(FEAT_TERMRESPONSE) || defined(PROTO)
  4987. /*
  4988.  * For Xterm >= 140 compiled with OPT_TCAP_QUERY: Obtain the actually used
  4989.  * termcap codes from the terminal itself.
  4990.  * We get them one by one to avoid a very long response string.
  4991.  */
  4992. static int xt_index_in = 0;
  4993. static int xt_index_out = 0;
  4994.  
  4995.     static void
  4996. req_codes_from_term()
  4997. {
  4998.     xt_index_out = 0;
  4999.     xt_index_in = 0;
  5000.     req_more_codes_from_term();
  5001. }
  5002.  
  5003.     static void
  5004. req_more_codes_from_term()
  5005. {
  5006.     char    buf[11];
  5007.     int        old_idx = xt_index_out;
  5008.  
  5009.     /* Don't do anything when going to exit. */
  5010.     if (exiting)
  5011.     return;
  5012.  
  5013.     /* Send up to 10 more requests out than we received.  Avoid sending too
  5014.      * many, there can be a buffer overflow somewhere. */
  5015.     while (xt_index_out < xt_index_in + 10 && key_names[xt_index_out] != NULL)
  5016.     {
  5017.     sprintf(buf, "\033P+q%02x%02x\033\\",
  5018.               key_names[xt_index_out][0], key_names[xt_index_out][1]);
  5019.     out_str_nf((char_u *)buf);
  5020.     ++xt_index_out;
  5021.     }
  5022.  
  5023.     /* Send the codes out right away. */
  5024.     if (xt_index_out != old_idx)
  5025.     out_flush();
  5026. }
  5027.  
  5028. /*
  5029.  * Decode key code response from xterm: '<Esc>P1+r<name>=<string><Esc>\'.
  5030.  * A "0" instead of the "1" indicates a code that isn't supported.
  5031.  * Both <name> and <string> are encoded in hex.
  5032.  * "code" points to the "0" or "1".
  5033.  */
  5034.     static void
  5035. got_code_from_term(code, len)
  5036.     char_u    *code;
  5037.     int        len;
  5038. {
  5039. #define XT_LEN 100
  5040.     char_u    name[3];
  5041.     char_u    str[XT_LEN];
  5042.     int        i;
  5043.     int        j = 0;
  5044.     int        c;
  5045.  
  5046.     /* A '1' means the code is supported, a '0' means it isn't.
  5047.      * When half the length is > XT_LEN we can't use it.
  5048.      * Our names are currently all 2 characters. */
  5049.     if (code[0] == '1' && code[7] == '=' && len / 2 < XT_LEN)
  5050.     {
  5051.     /* Get the name from the response and find it in the table. */
  5052.     name[0] = hexhex2nr(code + 3);
  5053.     name[1] = hexhex2nr(code + 5);
  5054.     name[2] = NUL;
  5055.     for (i = 0; key_names[i] != NULL; ++i)
  5056.     {
  5057.         if (STRCMP(key_names[i], name) == 0)
  5058.         {
  5059.         xt_index_in = i;
  5060.         break;
  5061.         }
  5062.     }
  5063.     if (key_names[i] != NULL)
  5064.     {
  5065.         for (i = 8; (c = hexhex2nr(code + i)) >= 0; i += 2)
  5066.         str[j++] = c;
  5067.         str[j] = NUL;
  5068.         if (name[0] == 'C' && name[1] == 'o')
  5069.         {
  5070.         /* Color count is not a key code. */
  5071.         i = atoi((char *)str);
  5072.         if (i != t_colors)
  5073.         {
  5074.             /* Nr of colors changed, initialize highlighting and
  5075.              * redraw everything. */
  5076.             set_color_count(i);
  5077.             init_highlight(TRUE, FALSE);
  5078.             redraw_later(CLEAR);
  5079.         }
  5080.         }
  5081.         else
  5082.         {
  5083.         /* First delete any existing entry with the same code. */
  5084.         i = find_term_bykeys(str);
  5085.         if (i >= 0)
  5086.             del_termcode_idx(i);
  5087.         add_termcode(name, str, FALSE);
  5088.         }
  5089.     }
  5090.     }
  5091.  
  5092.     /* May request more codes now that we received one. */
  5093.     ++xt_index_in;
  5094.     req_more_codes_from_term();
  5095. }
  5096.  
  5097. /*
  5098.  * Check if there are any unanswered requests and deal with them.
  5099.  * This is called before starting an external program or getting direct
  5100.  * keyboard input.  We don't want responses to be send to that program or
  5101.  * handled as typed text.
  5102.  */
  5103.     static void
  5104. check_for_codes_from_term()
  5105. {
  5106.     int        c;
  5107.  
  5108.     /* If no codes requested or all are answered, no need to wait. */
  5109.     if (xt_index_out == 0 || xt_index_out == xt_index_in)
  5110.     return;
  5111.  
  5112.     /* Vgetc() will check for and handle any response.
  5113.      * Keep calling vpeekc() until we don't get any responses. */
  5114.     ++no_mapping;
  5115.     ++allow_keys;
  5116.     for (;;)
  5117.     {
  5118.     c = vpeekc();
  5119.     if (c == NUL)        /* nothing available */
  5120.         break;
  5121.  
  5122.     /* If a response is recognized it's replaced with K_IGNORE, must read
  5123.      * it from the input stream.  If there is no K_IGNORE we can't do
  5124.      * anything, break here (there might be some responses further on, but
  5125.      * we don't want to throw away any typed chars). */
  5126.     if (c != K_SPECIAL && c != K_IGNORE)
  5127.         break;
  5128.     c = vgetc();
  5129.     if (c != K_IGNORE)
  5130.     {
  5131.         vungetc(c);
  5132.         break;
  5133.     }
  5134.     }
  5135.     --no_mapping;
  5136.     --allow_keys;
  5137. }
  5138. #endif
  5139.  
  5140. #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
  5141. /*
  5142.  * Translate an internal mapping/abbreviation representation into the
  5143.  * corresponding external one recognized by :map/:abbrev commands;
  5144.  * respects the current B/k/< settings of 'cpoption'.
  5145.  *
  5146.  * This function is called when expanding mappings/abbreviations on the
  5147.  * command-line, and for building the "Ambiguous mapping..." error messæge.
  5148.  *
  5149.  * It uses a growarray to build the translation string since the
  5150.  * latter can be wider than the original description. The caller has to
  5151.  * free the string afterwards.
  5152.  *
  5153.  * Returns NULL when there is a problem.
  5154.  */
  5155.     char_u *
  5156. translate_mapping(str, expmap)
  5157.     char_u    *str;
  5158.     int        expmap;  /* TRUE when expanding mappings on command-line */
  5159. {
  5160.     garray_T    ga;
  5161.     int        c;
  5162.     int        modifiers;
  5163.     int        cpo_bslash;
  5164.     int        cpo_special;
  5165.     int        cpo_keycode;
  5166.  
  5167.     ga_init(&ga);
  5168.     ga.ga_itemsize = 1;
  5169.     ga.ga_growsize = 40;
  5170.  
  5171.     cpo_bslash = (vim_strchr(p_cpo, CPO_BSLASH) != NULL);
  5172.     cpo_special = (vim_strchr(p_cpo, CPO_SPECI) != NULL);
  5173.     cpo_keycode = (vim_strchr(p_cpo, CPO_KEYCODE) == NULL);
  5174.  
  5175.     for (; *str; ++str)
  5176.     {
  5177.     c = *str;
  5178.     if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL)
  5179.     {
  5180.         modifiers = 0;
  5181.         if (str[1] == KS_MODIFIER)
  5182.         {
  5183.         str++;
  5184.         modifiers = *++str;
  5185.         c = *++str;
  5186.         }
  5187.         if (cpo_special && cpo_keycode && c == K_SPECIAL && !modifiers)
  5188.         {
  5189.         int    i;
  5190.  
  5191.         /* try to find special key in termcodes */
  5192.         for (i = 0; i < tc_len; ++i)
  5193.             if (termcodes[i].name[0] == str[1]
  5194.                         && termcodes[i].name[1] == str[2])
  5195.             break;
  5196.         if (i < tc_len)
  5197.         {
  5198.             ga_concat(&ga, termcodes[i].code);
  5199.             str += 2;
  5200.             continue; /* for (str) */
  5201.         }
  5202.         }
  5203.         if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL)
  5204.         {
  5205.         if (expmap && cpo_special)
  5206.         {
  5207.             ga_clear(&ga);
  5208.             return NULL;
  5209.         }
  5210.         c = TO_SPECIAL(str[1], str[2]);
  5211.         if (c == K_ZERO)    /* display <Nul> as ^@ */
  5212.             c = NUL;
  5213.         str += 2;
  5214.         }
  5215.         if (IS_SPECIAL(c) || modifiers)    /* special key */
  5216.         {
  5217.         if (expmap && cpo_special)
  5218.         {
  5219.             ga_clear(&ga);
  5220.             return NULL;
  5221.         }
  5222.         ga_concat(&ga, get_special_key_name(c, modifiers));
  5223.         continue; /* for (str) */
  5224.         }
  5225.     }
  5226.     if (c == ' ' || c == '\t' || c == Ctrl_J || c == Ctrl_V
  5227.         || (c == '<' && !cpo_special) || (c == '\\' && !cpo_bslash))
  5228.         ga_append(&ga, cpo_bslash ? Ctrl_V : '\\');
  5229.     if (c)
  5230.         ga_append(&ga, c);
  5231.     }
  5232.     ga_append(&ga, NUL);
  5233.     return (char_u *)(ga.ga_data);
  5234. }
  5235. #endif
  5236.  
  5237. #if (defined(WIN3264) && !defined(FEAT_GUI)) || defined(PROTO)
  5238. static char ksme_str[20];
  5239. static char ksmr_str[20];
  5240. static char ksmd_str[20];
  5241.  
  5242. /*
  5243.  * For Win32 console: update termcap codes for existing console attributes.
  5244.  */
  5245.     void
  5246. update_tcap(attr)
  5247.     int attr;
  5248. {
  5249.     struct builtin_term *p;
  5250.  
  5251.     p = find_builtin_term(DEFAULT_TERM);
  5252.     sprintf(ksme_str, IF_EB("\033|%dm", ESC_STR "|%dm"), attr);
  5253.     sprintf(ksmd_str, IF_EB("\033|%dm", ESC_STR "|%dm"),
  5254.                      attr | 0x08);  /* FOREGROUND_INTENSITY */
  5255.     sprintf(ksmr_str, IF_EB("\033|%dm", ESC_STR "|%dm"),
  5256.                  ((attr & 0x0F) << 4) | ((attr & 0xF0) >> 4));
  5257.  
  5258.     while (p->bt_string != NULL)
  5259.     {
  5260.       if (p->bt_entry == (int)KS_ME)
  5261.       p->bt_string = &ksme_str[0];
  5262.       else if (p->bt_entry == (int)KS_MR)
  5263.       p->bt_string = &ksmr_str[0];
  5264.       else if (p->bt_entry == (int)KS_MD)
  5265.       p->bt_string = &ksmd_str[0];
  5266.       ++p;
  5267.     }
  5268. }
  5269. #endif
  5270.